Beruflich Dokumente
Kultur Dokumente
Linguagem de Programao I
3a edio
Fortaleza
2013
Qumica
Cincias
Biologia
Biolgicas
Artes
Artes
Plsticas
Informtica
Fsica
Matemtica
Pedagogia
Presidenta da Repblica
Dilma Vana Rousseff
Ministro da Educao
Aloizio Mercadante
Presidente da CAPES
Jorge Almeida Guimares
Diretor de Educao a Distncia da CAPES
Joo Carlos Teatini de Souza Climaco
Governador do Estado do Cear
Cid Ferreira Gomes
Designer Instrucional
Laurisa Nutting
Coordenadora Editorial
Rocylnia Isidio
Projeto Grfico e Capa
Roberto Santos
Ilustrador
Mikael Baima
Diagramador
Francisco Jos da Silva Saraiva
Sumrio
Apresentao.................................................................................................5
Parte 1 - Introduo Programao de Computadores...............7
Captulo 1 - Fundamentos........................................................................9
1. Introduo Programao de Computadores.......................................9
2. A Linguagem Pascal.............................................................................11
3. Utilizando um Compilador Pascal........................................................12
4. Elementos Essenciais da Linguagem Pascal......................................16
4.1. Palavras Reservadas e Identificadores.........................................16
4.2. Estrutura Bsica de um Programa Pascal....................................17
4.3. Variveis........................................................................................19
4.4. Constantes....................................................................................22
4.5. Operadores e Expresses............................................................24
4.6. Comandos de Entrada e Sada.....................................................28
4.7. Tomando Decises........................................................................31
4.8. Utilizando Laos............................................................................36
4.9. Funes e Procedimentos............................................................44
5. Estudos de Caso..................................................................................51
5.1. Converso Celsius em Fahrenheit................................................51
5.2. Anlise do IMC..............................................................................52
5.3. Maior de Trs Valores...................................................................53
5.4. Ordenao de Trs Nmeros........................................................54
5.5. Somando Quadrados....................................................................55
5.6. Somatrio Condicional..................................................................56
5.7. Nmeros Primos...........................................................................57
Captulo 4 - Ponteiros.............................................................................109
1. Fundamentos.....................................................................................109
2. Declarao e Inicializao de Ponteiros............................................ 111
3. Ponteiros e Arrays..............................................................................115
4. Ponteiros em Mdulos........................................................................117
5. Alocao Dinmica............................................................................121
5.1. Alocao Dinmica Escalar........................................................122
5.2. Alocao Dinmica Vetorial........................................................123
5.3. Usando Ponteiros No Tipados..................................................126
6. Problemas com Ponteiros..................................................................128
7. Estudo de Caso: Lista Escadeada Elementar....................................129
Parte 3 - Modularizao.........................................................................135
Captulo 5 - Modularizao...................................................................137
1. Noes de Controle e Processo........................................................137
2. Parmetros Formais e Reais..............................................................139
3. Modos de Passagem de Argumentos................................................140
4. Recursividade ...................................................................................145
5. Aninhamento Modular........................................................................148
6. Unidades............................................................................................150
Captulo 6 - Arquivos..............................................................................157
1. Memria Secundria..........................................................................157
2. Fluxos.................................................................................................159
3. Modos de Acesso...............................................................................161
4. Utilizando Arquivos Binrios...............................................................165
5. Utilizando Arquivos de Texto..............................................................172
Sobre o autor.............................................................................................179
Apresentao
Sejam bem vindos ao mundo da programao de computadores! Tratase de um mundo fascinante e sofisticado que evolui constantemente no intuito
de agilizar o trabalho das pessoas envolvidas com tecnologia da informao.
No existe apenas uma forma de programar um computador. Na realidade
cada rea de conhecimento abrangida pela computao est ligada a alguma
categoria de programao que se caracterizam por suas prprias ferramentas
e linguagens.
Assim, por exemplo, um programador de sistemas operacionais trabalha no desenvolvimento de ferramentas que permitam melhor acessibilidade
do hardware, um programador de jogos almeja usar ao mximo o potencial
grfico disponvel para desenvolver aplicativos para entretenimento, um programador de sistemas informativos cria softwares que permitam s pessoas
interagirem atravs de uma rede particular ou da internet, um programador
de interfaces objetiva maximizar o aproveitamento de aplicaes locais ou
remotas utilizando todo aparato visual moderno e assim por diante. Cada uma
destas reas requer especializao.
Entretanto em todos os casos os programadores precisam de conhecimentos essenciais adquiridos em disciplinas bsicas sobre programao
de computadores. Estes conhecimentos passam pela estudo das chamadas
linguagens de programao que, de forma geral, consistem de poderosos artifcios para a expresso de instrues a serem executadas por computadores.
Este livro tem por objetivo apresentar e explorar conceitos essenciais
da linguagem de programao Pascal. Esta linguagem foi desenvolvida para
ser fcil de compreender e utilizar. De fato ela foi criada para ser ensinada e
por essa razo tem boa aceitao entre iniciantes em programao. Alm do
mais uma vez compreendida a linguagem Pascal torna-se consideravelmente
mais simples tanto migrar para outras linguagens como ingressar numa rea
de especializao como aquelas citadas ante- riormente.
A estrutura bsica do livro consiste de seis captulos divididos em trs
unidades. A primeira unidade trata de toda parte fundamental da linguagem de
forma que possvel ao final dela j construir aplicaes que funcionem. As
duas unidades finais so adendos para sofisticao e potencializao do que
foi aprendido na primeira unidade. Em termos gerais o objetivo do livro permitir que o leitor programe o mais prematu- ramente possvel de forma prtica,
desafiadora e estimulante.
O autor
Parte
Introduo Programao de
Computadores
Captulo
Fundamentos
Objetivos:
Esta unidade tem por objetivo introduzir o estudante no aprendizado da
linguagem de programao Pascal. No Captulo 1 so apresentadas a
sintaxe bsica bem como as estruturas fundamentais para implementao de pequenos programas funcionais. No Captulo 2 a linguagem
expandida atravs do estudo de estruturas sequenciais que permitem a
representao e manipulao de listagens de dados auxiliando o estudante a lidar com a resoluo de problemas mais complexos.
1. Introduo Programao de
Computadores
No princpio no havia a distino entre hardware e software e os primeiros
computadores eram programados diretamente em seus circuitos. Consistia de
uma tarefa ardua e exigia profundo conhecimento da arquitetura e do funcionamento do equipamento. Tarefas elementares exigiam considervel tempo
de trabalho e erros eram frequentes. A evoluo do hardware e a concepo
do conceito de software deram uma guinada na histria dos computadores.
O software passou a representar a alma de um computador e sua inoculao
nos circuitos dos equipamentos passou a ser referenciada como instalao
de software.
Softwares so instalados em camadas, ou seja, um software, para
funcionar, utiliza outros softwares. A exceo naturalmente a camada de
software instalada diretamente sobre o hardware: o sistema operacional. As
demais camadas se instalam sobre este ou sobre uma ou mais camadas existentes. considerado um programa um software de aplicao especfica. H
programas para edio de imagens, reproduo de arquivos de som, navegao na internet, edio de texto e etc.
Um programa um arquivo que contm uma listagem de instrues de
mquina. Estas instrues devem ser executadas por uma CPU na ordem
que se apresentam no arquivo. Este processo denominado execuo do
Sistema Operacional:
O sistema operacional
um conjunto de
softwares que trabalham
cooperativamente para
proporcionar ao usurio
acesso a recursos
do computador. Ele
esconde detalhes,
muitas vezes complexos,
de funcionamento do
hardware atravs de
abstraes simples.
Exemplos so Linux,
Windows, OS2, Unix e etc
10
Linguagem de Programao I
2. A Linguagem Pascal
A linguagem de programao Pascal foi originalmente projetada por Niklaus
Wirth na dcada de 1970. A linguagem tem absorvido desde essa poca muitas contribuies que convergiram para a criao de diversos compiladores
importantes. Atualmente possvel encontrar na Internet mais de 300 compiladores ou interpretadores da linguagem (alguns pagos, outros gratuitos
e muitos descontinuados, ou seja, no possuem mais suporte). Veja www.
Pascaland.org para uma lista completa de compiladores Pascal. As mais
notveis contribuies para o desenvolvimento do Pascal foram feitas pela
Borland (empresa americana de desenvolvimento de software) com a criao
do Turbo Pascal e posteriormente do Delphi Pascal.
A linguagem Pascal originalmente estruturada, ou seja, os programas
so construdos como um conjunto de pequenos subprogramas que se conectavam por chamadas (uma chamada de um determinado subprograma
a solicitao de execuo de outros subprogramas a partir dele). A linguagem
absorveu com o passar do tempo o paradigma da orientao a objetos (que
se baseia nos conceitos de classes e objetos) dando origem ao Object Pascal.
11
12
Arquitetura do
Processador:
Define o leiaute e
a capacidade de
armazenamento ou
processamento dos
componentes de uma
unidade central de
processamento (CPU).
As arquiteturas mais
populares hoje em dia
possuem de um a dois
ncleos (em ingls,
single core e dual core) e
tamanhos de registradores
(memria interna da CPU)
de 32 ou 64 bits.
Janela de Terminal:
Uma janela de terminal
a forma mais primitiva que
um sistema operacional
oferece ao usurio
para requisies de
tarefas. Todas as aes
so repassadas como
instrues escritas
denominadas de linhas de
comandos. Para indicar
que novas instrues
podem ser digitadas,
um terminal dispe um
indicador de entrada
denominado prompt
seguido de um cursor
piscante. Para confirmar
entradas o usurio
pressiona ENTER aps
cada linha de comandos e
aguarda o processamento
que normalmente se
encerra com a reexibio
do prompt aguardando
novas instrues.
O Turbo Pascal e o Delphi Pascal constituem a base de desenvolvimento do compilador Free Pascal abordado neste livro e recomendado aos
leitores (veja www.freePascal.org). Trata-se de um compilador livre, de crescente popularidade e que reconhece cdigos em Pascal puramente estruturado (como acontecia no Turbo Pascal), cdigos em Object Pascal (como
acontece com o Delphi) ou associao de cdigo (parte estruturada e parte
orientada a objetos)
Abordaremos neste livro apenas os elementos estruturados do Free
Pascal (que incluem os fundamentos da linguagem, variveis e constantes,
operadores, expresses, controle de fluxo, strings e arrays, tipos de dados
personalizados, ponteiros, modularizao e arquivos) que permitiro ao leitor
posterior extenso ao Object Pascal (que inclui ainda uso de classes e objetos, uso de interfaces, programao genrica, sobrecarga de operadores e
manipulao de excees).
Se o compilador estiver devidamente instalado ser impressa uma listagem das opes bsicas de uso. A seguir mostramos um fragmento que
antecede a listagem propriamente dita e que trs informaes do compilador.
Free Pascal Compiler version 2.2.4-3 [2009/06/04] for i386
Copyright (c) 1993-2008 by Florian Klaempfl
/usr/lib/fpc/2.2.4/ppc386 [options] <inputfile> [options]
Linguagem de Programao I
13
e no Unix e Linux:
./teste
Um compilador no
pode corrigir os erros
que lista porque, em sua
abrangente viso, h
muitas possibilidades de
correo de um mesmo
erro. Para ajudar ento no
trabalho do programador
o compilador gera o
mximo de documentao
de erro que permite mais
facilmente a soluo do
problema. O processo de
resoluo de erros num
programa conhecido
como depurao (em
ingls, debug).
14
Linguagem de Programao I
15
16
Para mais detalhes sobre a Free Pascal IDE consulte o guia do usurio
(users guide) na documentao do compilador.
Linguagem de Programao I
17
for
not
string
array
function
of
then
asm
goto
on
to
begin
if
or
true
case
implementation
packed
type
const
in
procedure
unit
dispose
inline
program
until
div
interface
record
uses
do
label
repeat
var
exit
mod
set
while
false
new
shl
with
file
nil
shr
xor
dia_de_sol
__1987q
_223 AxZ9 CARRO
Regras de Escopo:
So regras que definem
restries de acessos
entre partes distintas de
um mesmo programa. Elas
permitem, por exemplo,
a implementao de
programas grandes atravs
de fragmentos menores
fceis de gerenciar.
18
Todo programa em linguagem Pascal deve iniciar com a palavra reservada program seguida de um identificador (nome do programa; neste caso,
teste) seguido de ponto-e-vrgula. Logo abaixo devem ser colocadas, quando
necessrias, as declaraes globais do programa (global significa disponvel
para todo programa). Uma declarao um cdigo que viabiliza a utilizao
de um recurso do computador. As declaraes em linguagem Pascal so dispostas em sesses (unidades, tipos, constantes, variveis e mdulos) que so
estudadas ao decorrer do livro.
As respectivas palavras reservadas begin e end, representam os delimitadores do bloco ou corpo principal do programa: todo contedo entre begin
(que significa incio) e end (que significa fim) representa o programa propriamente dito a ser executado. A construo de um programa Pascal enfim a
implementao do cdigo no bloco principal que eventualmente requer por
recursos adicionais via declaraes. O ponto (.) marcado aps o end na ltima
linha faz parte da sintaxe da linguagem e formaliza o trmino do programa.
Sub-rotina:
So trechos de cdigofonte que funcionam como
programas independentes.
Programas e unidades
em Pascal so de fato
aglomeraes de subrotinas. As sub-rotinas so
tambm conhecidas como
subprogramas. Adiante
veremos que sub-rotinas
em Pascal podem ser
procedimentos ou funes
e que por essa razo
utilizamos o termo mdulo
para nos referirmos a
ambos.
Comentrios so fragmentos de textos no compilveis escritos conjuntamente ao cdigo-fonte e cuja funo documentar o programa. Pode-se
comentar contedo em Pascal colocando uma ou mais linhas entre chaves ou
entre /* e */ ou prefixando cada linha com // (veja exemplos no cdigo anterior).
Uma sesso de unidades declara bibliotecas conhecidas como unidades em Pascal. Unidades contm sub-rotinas desenvolvidas por outros programadores que se tornam disponveis nos programas onde so declaradas
tais unidades (Vrias unidades so distribudas com o compilador Pascal e
esto disponveis aps sua instalao).
Listagem 1
01
program primeiro_exemplo;
02
03
begin
04
modulo1;
05
modulo2(34);
06
modulo3(12, teste);
07
end.
Linguagem de Programao I
4.3. Variveis
Uma varivel um artifcio das linguagens de programao que permite o
programador utilizar de forma iterativa a memria do computador. O programador define que variveis o programa dever utilizar e elas sero criadas na
memria quando o programa for executado. Cada varivel se vincula a uma
clula de memria real de forma que as operaes programadas em cdigo
afetaro a memria quando o programa estiver rodando.
Basicamente uma varivel pode verificar ou modificar a clula de memria a qual est ligada. As operaes de mudana e verificao de valor, por
uma varivel so chamadas respectivamente de operaes de escrita e leitura.
A leitura no afeta o contedo da varvel ao passo que a escrita sobrescreve o
valor que a varivel contm com um novo valor (o valor sobrescrito perdido).
A sesso de declarao de variveis a sesso do programa destinada
a identificao (definio) de todas as variveis que sero utilizadas. Tentar
usar uma varivel no declarada faz o compilador emitir um erro de sintaxe.
Cada nova varivel precisa de um nome (que um identificador) e um
tipo (que uma palavra reservada). O tipo dir ao compilador que valores e
operaes sero suportados por aquela varivel. Tipos podem ser primitivos e
derivados. Os tipos primitivos so aqueles definidos nativamente pelo Pascal
ao passo que os derivados so construdos pelo programador a partir de tipos
primitivos (veja os Captulos 2, 3 e 4 para mais detalhes).
19
20
Tamanho (bytes)
1
1
2
2
2 ou 4
4
4
4
8
8
Linguagem de Programao I
21
Faixa
depende da plataforma
1.5E-45 .. 3.4E38
5.0E-324 .. 1.7E308
1.9E-4932 .. 1.1E4932
-2E64+1 .. 2E63-1
-922337203685477.5808 ..
922337203685477.5807
Tamanho (bytes)
4 ou 8
4
8
10
8
8
Tipos lgicos ou booleanos so utilizados para definir variveis que assumam apenas os valores verdadeiro e falso. Estes valores so representados em Pascal respectivamente pelas palavras reservadas True e False.
Uma varivel lgica teoricamente representada por um nico bit, mas na
prtica existem quatro tipos booleanos em Pascal com pelo menos 1-byte,
como mostrado na Tabela-1.4 (palavra reservada versus tamanho em bytes).
O tipo boolean o mais difundido sendo suficiente na maioria das aplicaes
que precisam de variveis booleanas.
22
Tipo
Tamanho (bytes)
Boolean
1
ByteBool
1
WordBool
2
LongBool
4
Tabela 4 - Tipos lgicos da Linguagem Pascal
No caso de tipos primitivos, sizeof possui aplicao importante na determinao dos tamanhos de integer e real haja vista dependerem da plataforma
utilizada (hardware).
4.4. Constantes
Uma constante um artifcio das linguagens de programao que permite a
manuteno de valores invariantes durante toda execuo do programa. Uma
constante pode aparecer num cdigo como parte integrante de uma expresso (veja prxima sesso) ou vinculada a uma clula de memria independente (como nas variveis), mas com suporte apenas a verificao (nunca a
escrita). Nas expresses,
Linguagem de Programao I
x*25
3.45-y
a + ch
hoje foi + st
b/100
my_bool = True;
23
24
Observe que a tipagem de q no necessrio pois o compilador detectaria 11 como inteiro. Nos casos de ex e st a tipagem necessria pois, sem
elas, ex seria inteiro e st caractere.
program atribuicoes;
02
var
03
i: integer;
04
x, info_2: real;
05
db: double;
06
b: boolean;
07
begin
08
i := 35;
09
x := 4.87;
10
info_2 := x * i;
11
12
b := True;
13
end.
A Listagem 2 demonstra a construo de cinco atribuies com expresses diversificadas. O operador de atribuio apenas um exemplo de operador.
A linguagem Pascal disponibiliza diversos operadores divididos nas categorias,
Operador de atribuio
Operadores aritmticos
Operadores relacionais
Operadores lgicos
Operadores de ponteiros
Operadores bit-a-bit
Linguagem de Programao I
Denomina-se precedncia de operaes a ordem que o compilador resolve as sub operaes que constituem uma expresso. Numa expresso aritmtica a sequencia de resolues a mesma definida pela matemtica, ou seja,
primeiro as multiplicaes (*) e divises (/, div ou mod), depois adies (+) e
subtraes (-). Assim em, x+3*y, feita primeira a multiplicao depois a soma.
Se operadores de mesma precedncia aparecem adjacentes numa mesma expresso, o compilador far a avaliao seguindo a sequencia em que esto,
da esquerda para a direita. Assim por exemplo a expresso, 20 mod 11 div 2,
resulta em 4 porque mod resolvido antes de div. De forma similar a expresso,
100 div 3 div 2 div 5, reduzida pelo compilador na sequencia,
25
26
Para quebrar a ordem de precedncia seguida nas avaliaes de expresses, pode-se utilizar parnteses como em, (3+x)*y. Neste exemplo a
soma realizada primeiro.
Operadores relacionais so aqueles que comparam dois valores (que
podem ser ou no numricos) e resultam num valor booleano, ou seja, verdadeiro ou falso. Por exemplo a expresso,
x > 10
utiliza o operador relacional maior que (>) e retorna verdadeiro (se o valor em
x maior que 10) ou falso (se o valor em x menor ou igual a 10). A tabela
seguinte lista os operadores relacionais da linguagem Pascal e seus respectivos significados:
Operador Relacional
Significado
>
Maior que
<
Menor que
>=
Maior ou igual a
<=
Menor ou igual a
<>
Diferente de
Igual a
Linguagem de Programao I
Significado
and
Conjuno
or
Disjuno
xor
Disjuno exclusiva
not
Negao
B
TRUE
FALSE
TRUE
FALSE
A and B
TRUE
FALSE
FALSE
FALSE
A or B
TRUE
TRUE
TRUE
FALSE
A xor B
FALSE
TRUE
TRUE
FALSE
not A
FALSE
FALSE
TRUE
TRUE
Em Pascal, expresses booleanas conectadas com operadores lgicos, precisam estar entre parnteses. Isso acontece porque os operadores
lgicos tm precedncia sobre os operadores relacionais de forma que uma
expresso do tipo, x>0 and x<100, sem parnteses, tem primeiramente avaliado o and, que neste caso significa operar a sub expresso, 0 and x. Mesmo
que isso tivesse algum sentido para o programador ainda restariam por se re-
27
28
x>10
y<=7
(a<100) or (b>500)
x diferente do em y ou o em a diferente
do em b
Linguagem de Programao I
writeln
read
readln
Listagem 3
01
program entrada_e_saida;
02
var
03
04
x: integer;
begin
05
06
read(x);
07
08
readln;
09
end.
29
30
2. Valor de x fornecido:
Fornecer valor de x: 32_ <enter>
3. Impresso da resposta:
Fornecer valor de x: 32
4. Encerramento:
Fornecer valor de x: 32
o dobro de x vale 64
o dobro de x vale 64
_
_
Linguagem de Programao I
Var.
a
b
x
y
Tipo
integer
real
integer
real
Valor
81
37.92
35
6.7541
Exemplo
writeln(tenho,a,anos);
write(b);
write(Carros: , x:6)
Writeln(>,y:7:2, gramas);
Sada
tenho81anos
3.79200000000000E+001
Carros: 35
> 6.75 gramas
As palavras reservadas if (que significa se) e then (que significa ento) marcam o incio de um processo de deciso. Elas reservam entre si uma
expresso booleana, representada aqui por <teste>. Quando o resultado
verdadeiro o contedo de <bloco> executado. Do contrrio o processo se
encerra e o programa continua sua execuo. O ponto-e-vrgula (;) marca o
fim sinttico da gramtica de deciso de forma que se <teste> falso ento o
programa desvia sua execuo para logo aps esta marcao.
Uma deciso bidirecional aquela que deve decidir entre executar um
de dois blocos sem possibilidade de execuo de ambos. Sua estrutura fundamental em Pascal dada por,
31
32
if <teste> then
<bloco_1>
else
<bloco_2>;
Linguagem de Programao I
writeln(p/2);
Se uma sequncia formada por mais de uma linha de comando precisa de execuo condicional, ento a formao do bloco dever incluir as
palavras chaves begin e end. Estas so respectivamente dispostas antes e
depois das linhas de comando formando o novo bloco da estrutura if..then. As
estruturas finais, nas decises unidirecional e bidirecional, envolvendo blocos
de linhas de comando, so respectivamente:
if <teste> then
if <teste> then
begin
begin
<linhas de comando>
<linhas de comando>
end;
33
34
if <teste1> then
if <teste2> then
<bloco1>
else
<bloco2>
else
if <teste3> then
<bloco3>
O if..then..else marcado com 1 bidirecional e aninha, no primeiro bloco, o if..then..else bidirecional marcado com 2 e no segundo bloco o if..then
unidirecional marcado com 3. Dessa forma bloco1 s executa se teste1 e teste2
forem verdadeiros; bloco2 s executa se teste1 for verdadeiro e teste2 for falso;
e por fim bloco3 s executa se teste1 falso e teste3 verdadeiro.
4.7.2. Decises Mltiplas
Uma deciso mltipla em Pascal aquela que lida com diversas possibilidades de caminhos a se seguir. Cada possibilidade representada por um bloco
de cdigo e apenas um destes blocos ter o contedo executado. Como as
expresses booleanas s encaminham para no mximo duas rotas, elas no
so a base de construo de uma deciso mltipla em Pascal. Ao invs disso
utilizam-se expresses aritmticas que resultem em valores inteiros. Desta forma cada bloco de deciso fica atrelado a um valor inteiro distinto. A estrutura
de deciso mltipla em Pascal tem sintaxe,
case <expressao_aritmetica_inteira> of
<rotulo_1>: <bloco_1>;
<rotulo_2>: <bloco_2>;
<rotulo_n>: <bloco_n>;
else <bloco_alternativo>;
end;
As palavras reservadas case..of (que significam caso..seja) formam a coroa da estrutura de deciso mltipla que necessariamente deve ser encerrada
em end mais ponto e vrgula. A expresso aritmtica entre case e of deve resultar num dos valores inteiros rotulados no cdigo do corpo da estrutura. Cada
rtulo deve ser seguido de dois pontos (:) e do bloco de deciso (encerrado em
Linguagem de Programao I
a, b: real;
04 begin
05
writeln('Menu');
06
writeln('1-- somar');
07
writeln('2 - subtrair');
08
writeln('3 - multiplicar');
09
writeln('3 - dividir');
10
readln(op);
11
writeln('valores:');
12
readln(a, b);
13
case op of
14
15
16
17
4: if abs(b)>1.0e-5 then
18
19
20
21 end.
35
36
case x of
1,2,3: write('ok');
4: write('tchau!');
else write('invalido!');
end;
O primeiro bloco deste exemplo poder ser executado quando a varivel x conter 1, 2 ou 3. Uma listagem de rtulos usa vrgulas para separar os
rtulos que devem conduzir a um mesmo bloco.
Linguagem de Programao I
37
38
possvel acoplar decises a laos fazendo toda estrutura de deciso se tornar o bloco da estrutura de repetio. Este mecanismo bastante flexvel e permite a implementao de algoritmos mais sofisticados. O
exemplo a seguir ilustra o acoplamento entre um lao de contagem e uma
deciso unidirecional,
for i := 1 to 1000 do
if (i mod 7 = 0) and
(i mod 3 <> 0) then
write(i, ' ');
Laos podem ser aninhados em Pascal. Aninhar significa construir laos dentro de outros. No h restries da quantidade de aninhamentos numa
mesma construo. Cada lao em um aninhamento representa um nvel deste aninhamento. No exemplo,
for i:= 1 to 10 do
for j := 1 to 10 do
write(i*j);
h dois nveis de aninhamento. Diz-se que o segundo lao for est aninhado no primeiro. Semanticamente cada iterao do primeiro lao for provoca a execuo das dez iteraes do segundo lao for. Assim a instruo write
executada um total de 100 vezes. No exemplo,
for i:= 1 to 10 do begin
for j := 1 to 10 do write(i+j);
for j := 1 to 10 do write(i+j);
end;
o primeiro lao aninha outros dois laos que por sua vez no se aninham. Assim existem apenas dois nveis de aninhamento neste exemplo. O
comando write executado 200 vezes.
Linguagem de Programao I
As palavras reservadas while (que significa enquanto) e do (que significa faa) encapsulam a expresso booleana, <expressao>. Enquanto o valor
desta expresso for verdadeiro o cdigo em <bloco> repetido. Este bloco
pode ser formado por uma linha de comando ou por um conjunto delas desde
que encapsuladas pelas palavras reservadas begin/end;.
importante observar que o estado das variveis que formam a expresso devem ser modificadas dentro do bloco (ou por um agente externo ao programa), ou do contrrio o lao se tornar infinito (ou nunca ser executado).
No exemplo,
j := 1;
while j < 100 do
begin
os inteiros de 1 a 99 so impressos em
sada padro.
a varivel j age como contador que iniciado fora do lao. A atribuio, j := j+1,
permite que a expresso booleana de entrada do lao, j<=100, diferencie sua
avaliao de uma iterao para outra. Na primeira iterao do lao, j contm 1
e este o valor impresso por write. Nas demais iteraes a incrementao de
j geram novas impresses. Quando 99 impresso o valor em j incrementado
para 100 na linha seguinte. Quando o teste de entrada executar na prxima
vez (e ele ainda o ser), o avaliador encontrar a instruo 100<100 que resulta falso: neste ponto o lao encerrado. Assim 99 o ltimo valor impresso.
O lao anterior pode ser facilmente substitudo por um lao de contagem. H situaes entretanto que os laos de contagem no podem resolver, como em,
x := 145;
while x > 0 do begin
write(x mod 2);
x := x div 2;
end;
39
40
Linguagem de Programao I
te anulada fora do lao, Linha-04) conter, no final das iteraes, a somatria dos valores fornecidos pelo usurio (excluindo o zero). A varivel
auxiliar n permite a contagem de valores lidos. Ela anulada antes do
lao (Linha-05) e incrementada em uma unidade (Linha-12) cada vez que
um novo valor (no nulo) lido atravs de x. A mdia final naturalmente
s/n e impressa na Linha-16 desde que o valor em n no seja nulo (verificao feita pelo teste da Linha-15). Se n contm zero, a mensagem da
Linha-18 impressa ao invs da mdia.
Listagem 5
01
program media;
02
var s, x, n: integer;
03
begin
04
s := 0;
05
n := 0;
06
repeat
07
write('Valor: ');
08
readln(x);
09
if x <> 0 then
10
begin
11
s := s+x;
12
n := n+1;
13
end;
14
until x=0;
15
if n>0 then
16
17
18
19
41
42
Este lao teoricamente infinito porque a expresso booleana de teste simplesmente True. Entretanto, quando zero fornecido, o teste do if
se torna verdadeiro e break acionado, quebrando o lao. Observe que os
incrementos de s e n no so mais protegidos por um corpo de deciso simplesmente porque no sero mais executados aps a quebra do lao. O efeito
deste lao o mesmo daquele na Listagem-1.5.
Break tem efeito apenas sobre o lao em que est embutido. Numa
situao onde laos esto aninhados, break afeta o lao que o executa. Por
exemplo em,
while <expressao_1> do begin
...
while <expressao_2> do begin
...
if <expressao_3> then break;
end;
end;
break quebra o segundo while (se <expressao_3> verdadeira). Podem haver vrias quebras, dependendo do total de iteraes do primeiro while. J no
caso seguinte,
while <expressao_1> do begin
...
while <expressao_2> do begin
...
end;
if <expressao_3> then break;
end;
Linguagem de Programao I
// destino do desvio
...
goto <rotulo>;
end.
43
44
Listagem 6
01
program desvio;
02
var
03
04
05
06
n: integer;
label
rot;
begin
07
n := 1;
08
rot:
09
10
n := n+1;
11
12
end.
Linguagem de Programao I
constri uma chamada ao mdulo teste que requer dois argumentos de entrada. J em,
teste;
onde y atua como resgatador direto no primeiro caso e indireto no segundo. Caso teste seja um procedimento nestes ltimos exemplos, o compilador
acusar erro de sintaxe. Vale enfatizar que todas essas construes devem
encerrar em ponto-e-vrgula.
Para construir um procedimento sem argumentos em Pascal deve-se
utilizar a seguinte sintaxe,
procedure <identificador_do_nome>;
{ declaraes }
begin
{ corpo do procedimento }
end;
Procedimentos em Pascal devem iniciar com a palavra chave procedure seguida de um identificador (nome do mdulo). A linha contendo a palavra
reservada procedure chamada de prottipo ou interface do procedimento.
Sesses de declarao so suportadas, mas os recursos declarados so de
uso nico do procedimento. O bloco begin/end, restringe o corpo de cdigo
do procedimento e deve ser encerrado em ponto-e-vrgula. O programa da
Listagem 7 ilustra o uso de procedimentos Pascal sem argumentos.
45
46
Listagem 7
01 program usando_procedimento;
02
procedure meu_teste;
03
begin
04
05
06 begin
07
meu_teste;
08 end;
Linguagem de Programao I
Listagem 8
01 program teste_de_procedimentos;
02 var
03
n: integer;
04 { mdulos }
05 procedure print(n: integer);
06 begin
07
08 end;
09
10 procedure listar(m, n: integer);
11 var i: integer;
12 begin
13
for i := m to n do
14
print(i);
15 end;
16 { programa principal }
17 begin
18
readln(n);
19
listar(0, n);
20
listar(2*n, 3*n);
21 end.
47
48
3
O quadrado de 0 vale 0
O quadrado de 1 vale 1
O quadrado de 2 vale 4
O quadrado de 3 vale 9
O quadrado de 6 vale 36
O quadrado de 7 vale 49
O quadrado de 8 vale 64
O quadrado de 9 vale 81
Funes em Pascal devem iniciar com a palavra chave function seguida de um identificador (nome do mdulo). O prottipo de uma funo inclui
ainda o tipo da informao que a funo retorna (tipo de retorno) marcado
com dois-pontos seguido da palavra reservada do tipo. A estrutura de sesses
de declarao e de cdigo do corpo de uma funo so idnticos aos dos procedimentos. As funes ainda contam com uma varivel interna, cujo nome
o mesmo da funo e o tipo o de retorno, e cujo valor armazenado antes do
trmino da funo justamente o valor de retorno desta funo.
Linguagem de Programao I
49
50
Listagem 9
01
program teste_de_funcoes;
13
02
var
14
var i: integer;
15
begin
03
n: integer;
04
16
05
17
06
var i: integer;
18
07
begin
19
for i := 0 to max do
writeln('Fatorial de ', i, ' = ', fat(i));
end;
08
fat := 1;
20
09
for i := 1 to n do
21
readln(n);
10
fat := fat*i;
22
listar(n);
11
end;
23
begin
end.
12
Linguagem de Programao I
var
y: real;
procedure teste_2;
begin
writeln('ol');
end;
5. Estudos de Caso
Os estudos de casos a seguir aplicam a sintaxe bsica da linguagem Pascal
estudada neste captulo.
C (F 32)
=
5
9
51
52
program Celsius_para_Fahrenheit;
02
var
03
04
C, F: real;
begin
05
06
read(C);
07
F := C*9/5 + 32;
08
09
end.
Na Linha-07, v-se F isolado do lado esquerdo da atribuio e uma expresso sem parnteses do lado direito. O primeiro e o terceiro argumento do
writeln, Linha-08, fazem as temperaturas serem escritas com uma casa decimal e o mnimo de caracteres (o zero em :0:1 causa este efeito). A sada final
do programa aps o usurio fornecer uma temperatura de 27C a seguinte:
Valor de temperatura em Celsius: 27
27.0oC = 80.6oF
IMC =
p
2
h
Linguagem de Programao I
Listagem 11
01
program Calculo_IMC;
10
02
var
11
03
04
if (imc<20) then
12
begin
writeln('Magro!')
13
05
14
06
readln(altura);
15
07
16
08
readln(peso);
17
09
imc := peso/(altura*altura);
18
else
if (imc>25) then
writeln('Gordo!')
else
writeln('Normal!');
end.
program Maior_De_Tres;
10
writeln(a)
02
var
11
else
03
04
a,b,c: integer;
begin
12
13
05
14
06
readln(a,b,c);
15
07
write('Max(',a,',',b,',',c,') = ');
16
08
if a>b then
17
09
if (a>c) then
18
writeln(c)
else
if b>c then
writeln(b)
else
writeln(c);
end.
53
54
program Ordenacao_Tres_Numeros;
13
t := a;
02
var
14
a := c;
03
04
a, b, c, t: integer;
begin
15
c := t;
16
end;
if b>c then begin
05
17
06
readln(a,b,c);
18
t := b;
07
19
b := c;
08
t := a;
20
c := t;
09
a := b;
21
end;
10
b := t;
22
11
12
end;
if a>c then begin
23
end.
Linguagem de Programao I
program Somatorio_Quadratico;
var
i, max, S: integer;
begin
S := 0;
for i := 0 to max do
S := S + i*i;
end.
Na Linha-05 a varivel S, que conter ao final do processamento o somatrio desejado, recebe zero marcando o incio do somatrio. O lao da
Linha-08 tem como limite superior a prpria varivel max indicando que o somatrio vai de fato at o valor lido na Linha-07. A expresso do lado direito da
atribuio na Linha-09 contm a prpria varivel que sofrer a atribuio (S).
55
56
program Somatorio_Condicional;
06
02
var
07
03
04
05
n, S: integer;
begin
08
09
S := 0;
for n := 0 to 500 do
10
S := S + n;
writeln('Soma = ', S);
end.
Linguagem de Programao I
program primos;
16
02
17
03
04
var d: integer;
05
06
res: boolean;
begin
e_primo := res;
end;
19
20
begin
21
i := 2;
07
d := 2;
22
cnt := 0;
08
res := true;
23
while
09
24
10
25
11
res := false;
26
12
break;
27
end;
end;
28
i := i+1;
d := d + 1;
29
13
14
15
end;
30
end;
end.
57
58
Atividades de avaliao
1. Faa um programa para o computador calcular o quadrado de um nmero.
2. Faa um programa para o computador determinar o valor mximo entre
dois nmeros inteiros A e B.
3. Faa o programa para calcular a mdia das notas de uma turma de 20
alunos.
4. Faa um programa que receba as dimenses de uma caixa dgua e
calcule o seu volume.
5. Modifique o programa da questo 04 de forma que a sada seja a quantidade em metros quadrados de material necessrio a construo da caixa. Considere a presena de tampa.
6. Dois alunos fizeram trs provas cada um cujas notas so conhecidas
Faa um programa que diga qual deles tem a maior mdia.
7. Construa um programa que receba dois valores inteiros a e b e retorne
como sada ab.
8. Construa um programa que receba os lados de um tringulo e indique se
ele existe ou no. Em caso afirmativo imprimir tambm: a) se ele retngulo, acutngulo ou obtusngulo; b) valor de sua rea.
9. Faa um programa para calcular o fatorial de um nmero N inteiro dado.
Linguagem de Programao I
59
Captulo
Strings e Arrays
1. Caracteres e Strings
A maior parte de toda informao gravada em mdias digitais, incluindo aquela
disponvel via internet, est em formato texto. Textos, em computadores, so
representados por strings que por sua vez so representadas pela unio sequencial (concatenao) de unidades grficas de informao denominadas
caracteres. A presena de recursos de manipulao de strings numa linguagem de programao essencial. Tais recursos so normalmente disponibilizados atravs de bibliotecas ou de comandos nativos (previstos no projeto
original da linguagem e implementados juntamente com ela). Pascal conta
com recursos nativos para a manipulao de texto.
1.1. Caracteres
Pascal possui o tipo de dados primitivo char para representar caracteres independentes (que no fazem parte de uma string). Assim,
var
ch: char;
ASCII:
abreviao de American
Standard Code for
Information Interchange
que significa Cdigo
Padro Americano para o
Intercmbio de Informao.
62
cod
ASCII
32
cod
ASCII
cod
ASCII
cod
ASCII
cod
ASCII
42
52
62
>
72
33
43
53
63
73
34
44
54
64
74
35
45
55
65
75
36
46
56
66
76
37
47
57
67
77
38
&
48
58
68
78
39
49
59
69
79
40
50
60
<
70
80
41
51
61
71
81
cod
ASCII
cod
ASCII
cod
ASCII
cod
ASCII
cod
ASCII
82
92
102
112
122
83
93
103
113
123
84
94
104
114
124
85
95
105
115
125
86
96
106
116
126
87
97
107
117
88
98
108
118
89
99
109
119
90
100
110
120
91
101
111
121
'A'
'$'
'7'
'_'
' '
Linguagem de Programao I
ENTER
#27 ESC
#9 TAB
#8 BACKSPACE
// A
writeln('B', '%');
// B%
// A98#
', ord(ch));
end.
63
64
(107) e somar resultado ao do cdigo do caractere A (75). Como as letras, tanto maisculas como minsculas, so sequencias contnuas (veja Tabela-2.1),
este procedimento deve fazer retornar um cdigo ASCII conveniente para a
verso maiscula. A funo maiuscula na Listagem 17 recebe um caractere,
verifica se uma letra minuscula (Linha-03) e, caso seja, retorna sua verso
maiscula (calculada pela expresso na Linha-04), do contrrio retorna o prprio caractere de entrada (Linha-06).
Listagem 17
01
02
begin
03
04
05
eles
06
07
// -32 75-107
maiuscula := ch;
end.
O tamanho, quando especificado, definido entre colchetes, [ ], e ps-fixado palavra reservada string. Strings de tamanho definido em Pascal s
suportam at 255 caracteres. Especificar um valor maior que esse causa um
erro de compilao. A restrio de tamanho imposta por este tipo de construo classifica as strings declaradas como strings curtas. Tais strings podem
ser alternativamente declaradas pela palavra reservada shortstring (sem especificao de tamanho). Exemplo,
var sst: shortstring;
Linguagem de Programao I
Diretivas de Prprocessamento ou
simplesmente Diretivas:
tratam-se de cdigos
escritos entre chaves, { },
pr-fixados pelo smbolo $
e que servem normalmente
para ligar, desligar ou
modificar recursos do
compilador. Exemplo, {$I+}.
program teste;
program teste;
program teste;
program teste;
var
{$H-}
var
var
var
x:
string[255];
x:
shortstring;
{}
{}
x: string;
{}
x: string;
{}
program teste;
{$H+}
var
var
x: ansistring;
x: string;
{}
{}
65
66
Variveis de tipo string podem ser atribudas diretamente a outras mesmo quando seus comprimentos so distintos. Quando uma string recebe o
contedo de outra string, seu contedo primeiramente eliminado da memria
e em seguida sua referncia (o ponto da memria ao qual a string se refere)
mudado para o mesmo da string atribuda. Por exemplo em,
A := minha casa;
B := meu trabalho;
B := A;
faz a string meu trabalho ser eliminada da memria e a string minha casa passar
a ser referenciada tanto por A quanto por B. A priori acredita-se que qualquer
mudana em A afetar B (e vice-versa) numa nova atribuio. Mas isso no
acontece. Se algum cdigo mais adiante tentar modificar A ou B (no apenas
ler, mas modificar!), uma cpia da string ser feita antes da modificao e atribuda a quem solicitou a mudana (A ou B). Novamente as strings possuiro
referncias distintas (uma mantida e outra modificada). Exemplo,
A := 'minha casa';
// A no endereo 1
B := 'meu trabalho';
// B no endereo 2
B := A;
// A e B no endereo 1 e nada mais em 2
A := 'minha vida';
// B no endereo 1 e A no endereo 3
Os comandos read e readln podem ser usados para ler strings curtas e
longas sem adicional de sintaxe como em,
read(fulano);
Linguagem de Programao I
// ola!
// ola!mundo
z := x + y;
// ola!ola!mundo
onde x uma string. Uma nova string criada do lado direito da atribuio pela
concatenao do contedo de x e fim. Com a atribuio, a antiga string inicial
em x eliminada da memria e x passa a se referenciar nova string oriunda
da concatenao.
Strings podem ser tambm concatenadas com caracteres, como em,
x := Caractere de ASCII 38 e: + #38; // Caractere de ASCII 38 e: &
onde V denota o valor (inteiro ou real) para ser convertido e armazenado na string
S (curta ou longa). A Listagem 18 ilustra o uso de str. As converses nas Linhas
09 e 10 colocam respectivamente nas variveis si e sp as verses string do inteiro
em idade e do real em peso. Observe que possvel converter a parte do valor real
que realmente interessa utilizando a notao de dois-pontos (:0:2 denota todas as
casas antes da vrgula e apenas duas depois). A string final gerada pela concatenao da Linha-11, armazenada na varivel s e impressa na Linha-12.
Listagem 18
01
02
03
program usando_str;
var
04
05
06
07
idade: integer;
peso: real;
begin
idade := 25;
08
peso := 60.5;
09
10
11
12
13
str(idade, si);
str(peso:0:2, sp);
end.
67
68
Linguagem de Programao I
Listagem 19
01
program valor_seguro;
02
03
04
var
05
entrada: string;
06
err: integer;
07
08
begin
repeat
09
10
readln(entrada);
11
12
if err<>0 then
13
writeln('inteiro invalido!')
14
else
15
16
17
break;
until False;
// Lao infinito
end;
18
19
var x: integer;
20
begin
21
x := inteiro_valido;
22
23
end.
// cb
ch := s[7];
// g
69
70
var
s: string[100];
begin
s := 'abcdefg';
writeln( length(s) );
// 7
end.
Listagem 20
01
program de_tras_pra_frente;
07
02
var
08
write('Inverso> ');
for i := length(s) downto 1 do
03
s: string[100];
09
04
i: integer;
10
05
06
begin
readln(s);
write( s[i] );
11
write('Entrada> ');
12
writeln;
end.
O acesso individual a caracteres proporcionado pelo operador de indexao leitura/escrita, ou seja, pode ser usado tanto para ler os caracteres
quanto para modific-los. Um exemplo interessante a converso de uma
string em sua verso maiscula. Utilizando a funo maiuscula da Listagem 17,
pode-se escrever,
read(s);
for i := 1 to length(s) do
s[i] := maiuscula( s[i] );
writeln(s);
// ver Listagem-2.1
Linguagem de Programao I
71
onde s pode ser uma string curta ou longa. O lao de contagem crescente varre a cadeia completa e modifica cada caractere para a sada
da chamada da funo maiuscula (que por sua vez recebe o caractere da
cadeia de entrada).
Strings podem ser comparadas com operadores relacionais. O critrio
de comparao adotado pelo compilador Pascal denominado critrio lexicogrfico. exatamente o mesmo critrio utilizado para fazer comparaes
e ento ordenar uma lista, por exemplo, de nomes de pessoas. Dadas duas
strings, a comparao lexicogrfica executa comparaes entre caracteres
de uma e de outra na mesma posio.
As comparaes partem do incio de cada string e se mantm enquanto
os caracteres forem idnticos ou uma das cadeias no extrapolar seu ndice
mximo. Quando surge no processo dois caracteres distintos, a comparao
termina e ser lexicograficamente maior a string cujo caractere comparado
tiver maior cdigo ASCII. Exemplos,
'casar' > 'casado'
Duas strings so idnticas em Pascal deste que tenham mesmo comprimento e mesma sequencia de caracteres.
Para obter uma substring de uma dada string, utiliza-se o comando
copy, unidade system, cuja sintaxe bsica ,
copy(S, I, cont);
Substring:
String formada por uma
subsequencia contnua
dos caracteres de uma
outra string. Na string
abcdefghij so exemplos
de substrings abc, cdefg
e ij.
72
s := 'ABCDEFG';
t := copy(s, 3, 4);
// CDEF
writeln( copy(t, 2, 2)
// DE
);
s := s + copy(s,4,4);
// ABCDEFGDEFG
onde s e t so variveis strings. A primeira extrao atribuda a t, a segunda repassada como parmetro de writeln e a terceira componente
de uma expresso.
Strings podem ser inseridas em outras, ou seja, possvel, utilizando
um nico comando, quebrar uma string W em W1 e W2 e depois fazer W se
tornar W1 + X + W2 onde X a string inserida. Para inserir uma string em outra,
utiliza-se o comando insert, unidade system, seguindo a sintaxe bsica,
insert(S1, S2, p);
onde S1 representa a string que ser inserida e S2 a string que sofrer a insero. A posio de insero em S2 dada pelo inteiro p. No exemplo,
s := '123';
tex := 'abcdef';
insert(s, tex, 4);
// abc123def
a string s inserida na string tex. A insero quebra tex em abc e def e depois
atribui a tex o resultado da concatenao abc + 123 + def. Insert no possui retorno (procedimento) mas modifica a string passada como segundo argumento.
Para remover caracteres de uma string utiliza-se o comando delete, unidade system, de sintaxe bsica,
delete(S, p, cont);
onde S denota a string que sofrer retrao, p a posio onde deve principiar a deleo e cont a quantidade de caracteres que devero ser eliminados.
Internamente delete efetua a quebra da string e concatena as partes que devem ser mantidas. Exemplo,
s := 'abcdefgh';
delete(s, 3, 4);
writeln(s);
//
abgh
onde s uma string. A deleo ocorre a partir da posio 3 e elimina 4 caracteres. Delete quebra S nas substrings {ab. cdef. gh }, concatena a primeira com
a terceira e atribui o resultado a S. O comando delete, assim como insert, no
possui valor de retorno mas modifica a string que recebe como argumento.
Linguagem de Programao I
2. Arrays
Uma array uma estrutura de dados que permite o armazenamento sequencial de dados de mesmo tipo. Cada unidade constituinte de uma array denominada clula e o tipo de dados comum a todas as clulas denominado
tipo base. Uma array referenciada em cdigo por uma nica varivel e suas
clulas por uma associao desta varivel, do operador de indexao, [ ], e de
um ou mais valores de ndices.
Strings so exemplos de arrays cujo tipo base char mas comumente
no recebem o ttulo (de array) por possurem propriedades prprias no presentes em arrays de outros tipos base. Manteremos a conveno distinguindo
strings de arrays. Arrays no podem ser diretamente concatenadas, comparadas, impressas por write/writeln ou lidas por read/readln. Veremos alguns cdigos
que permitiro gerar comportamentos equivalentes em arrays.
O comprimento de uma array igual ao total de clulas que a constitui e
pode tambm ser determinado pelo comando length que receber, neste caso,
a varivel array como argumento. Arrays no fazem distino entre comprimento teto e comprimento utilizado como nas strings. Dessa forma length retorna sempre o total de clulas alocadas em memria para a array, independente
do contedo.
Arrays em Pascal podem ser estticas e dinmicas. Uma array esttica aquela cujo comprimento predefinido na declarao e no pode ser
mais modificado em tempo de execuo. Arrays dinmicas so aquelas cujo
comprimento pode ser modificado a qualquer momento da execuo (tanto
expandindo como contraindo).
As clulas de arrays, sejam estticas ou dinmicas, suportam leitura/escrita
deste que o ndice utilizado esteja na faixa apropriada. A faixa apropriada em arrays estticas pode ser definida pelo programador tendo comumente como limite
inferior o valor 1. O ndice inferior de arrays dinmicas sempre zero.
Arrays podem possuir mais de uma dimenso. Uma array unidimensional representa, por exemplo, uma lista e necessita de um nico ndice para
referenciar suas clulas. Uma array bidimensional representa, por exemplo,
uma tabela ou uma matriz e precisa de dois ndices. Uma array tridimensional
utiliza trs ndices e assim por diante. No h restries em Pascal no nmero
de dimenses que uma array pode possuir.
73
74
neste exemplo os ndices limites so 1 e 100. Para alterar uma dada clula de
x usa-se,
x[34] := 152;
neste caso a trigsima quarta clula recebe o valor 152. Para fazer x receber
os 100 primeiros mpares, pode-se escrever,
for i := 1 to length(x) do
x[i] := 2*i - 1;;
em zero
Linguagem de Programao I
A memria ocupada por uma varivel array a somatria das memrias de suas clulas e pode ser determinada pelo comando nativo sizeof. No
exemplo,
var
y: array[1..20] of Longint;
// usa 80-bytes
program arrays_compativeis;
02
var
03
i, n: integer;
04
A: array[1..5] of integer;
05
B: array[1..5] of integer;
06
begin;;
07
n := 257;
08
09
A[i] := n;
10
n := n div 2;
11
end;
12
B := A;
13
14
for i := 1 to 5 do
15
16
75
76
// primeira sintaxe
quanto,
var
x: array[1..100, 1..50] of byte;
// segunda sintaxe
Linguagem de Programao I
77
Cada dimenso de uma array multidimensional esttica em Pascal possui sua prpria faixa de ndices encapsuladas pela palavra reservada array e
por colchetes individuais (primeira sintaxe) ou separadas por vrgulas e envolvidas num colchete comum (segunda sintaxe). Para acessar uma clula de
uma array multidimensional, seja para leitura seja para modificao, deve-se
informar os ndices na quantidade que forem as dimenses e nas faixas previstas na declarao. No caso de x tem-se por exemplo,
x[20, 17] := 65;
onde col e lin so inteiros. O aninhamento dos laos neste exemplo permite varrer para cada linha (primeiro lao) as clulas em cada coluna (segundo lao).
O total de iteraes portanto o nmero de clulas da array (25 neste caso).
Este nmero de iteraes tambm o de decises tomadas com if.
So exemplos de arrays de quantidade de dimenses superior a dois,
var
A: array[1..5, 1..10, 1..100] of boolean;
Teste: array[1..2, 1..2, 1..2, 1..5] of double;
Matriz Identidade:
Na matemtica a matriz
quadrada (nmero de
linhas igual ao de colunas)
cujos elementos so todos
nulos, exceto aqueles da
diagonal principal (diagonal
cujo ndice da linha e da
coluna so idnticos), que
valem 1.
78
contguas de clulas sendo o aspecto multidimensional um recurso da linguagem para melhorar a capacidade de abstrao.
Exemplo,
var
x: array of integer;
deve ser,
0 25
Linguagem de Programao I
Listagem 22
01 program arrays_dinamicas;
02 var
03
i: integer;
04
x, y: array of integer;
05 const
06
max = 5;
07 begin
08
setlength(x, max);
09
for i := 0 to max-1 do
10
x[i] := 2*i+1;
11
y := x;
12
for i := 0 to max-1 do
13
14
y[i] := 2*y[i];
15
for i := 0 to max-1 do
16 end.
', y[i] );
79
80
A atribuio direta de uma array dinmica a outra no gera uma nova array dinmica. Ao invs disso passam a existir duas referncias ao mesmo local
de memria. Isso ilustrado no programa da Listagem - 22. A array x alocada
na Linha-08 e recebe os valores dos primeiros cinco mpares (Linhas 09 e 10).
A atribuio direta na Linha-11 cria uma nova referncia para a memria
de x, ou seja, x e y agora se referem a mesma array dinmica. Nas Linhas 12
e 13 o contedo de cada clula da array dinmica y multiplicado por dois o
que equivalente a dobrar os valores das clulas de x. Assim as impresses
nas linhas 14 e 15 geram a sada,
2 2
6 6
10 10
14 14
18 18
nal
B: array of array of array of integer;
nal
Arrays dinmicas multidimensionais so tambm alocadas com setlength. Surge nele um argumento adicional para cada comprimento de dimenso
novo. Exemplos,
setlength(A, 2, 5);
da array A
setlength(B, 5, 3, 4);
da array B
e a alocao,
readln(n);
setlength(mat, n, n);
Linguagem de Programao I
onde lin e col so inteiros. Observe que na segunda chamada a length o argumento mat[0]. De fato se mat tivesse, por exemplo, cinco dimenses, o comprimento delas seriam calculados pelas respectivas instrues,
length( mat );
length( mat[0] );
length( mat[0][0] );
length( mat[0][0][0] );
length( mat[0][0][0][0] );
3. Estudos de Caso
3.1. Palndromos Numricos
Um palndromo qualquer sequencia de informao cuja disposio dos elementos na ordem reversa (de trs para a frente) origina a mesma sequencia.
As strings asa, abbba e tomamot so exemplos de palndromos. Palndromos
numricos so inteiros cuja sequencia de dgitos so palndromos. Exemplos
so 2, 121, 5665 e 10101.
A funo e_palind da Listagem 23 determina se seu argumento de entrada ou no um palndromo numrico. A primeira hiptese da funo de que
seja e por essa razo a varivel interna e_palind recebe true na Linha-05. O lao
entre as Linhas 08 e 11 determina quantos dgitos, t, possui o valor da entrada
em n. Para isso uma cpia deste valor feito para x e t iniciado com zero.
Cada iterao do lao reduz o valor em x para o quociente de sua razo por dez (Linha-10) e o lao encerra quando zero alcanado. Como t
incrementa da unidade em cada iterao, esta varivel conter no final das
iteraes a quantidade de dgitos do valor em n. Na Linha-12 a array dinmica
digs alocada para registrar os dgitos do valor em n e o lao entre as Linhas
13 e 16 carrega os dgitos. O lao decrescente para preencher os dgitos de
trs para frente (porque nesta ordem que eles so extrados). A expresso,
n mod 10, Linha-14, retorna o ltimo dgito do valor em n ao passo que, n := n div
10, Linha-15, fora sua extrao.
81
82
x, t, i: integer;
04 begin
05
e_palind := true;
06
x := n;
07
t := 0;
08
09
t := t + 1;
10
x := x div 10;
11
end;
12
setlength(digs, t);
13
14
15
n := n div 10;
16
end;
17
18
19
e_palind := false;
20
break;
21
22 end;
end;
Linguagem de Programao I
83
Subarray:
Array obtida a partir de
uma subsequncia de
clulas continuas de uma
array dada.
A ordenao por seleo de dat ocorre por ao dos laos entre as Linhas
14 e 21. A lao externo varre todas as clulas no intervalo 1..n-1 ao passo que o
lao interno busca, atravs de k, pela clula de menor valor no intervalo i..n. A primeira hiptese de k em cada iterao do lao externo o valor em i (Linha-15).
As trocas entre as clulas de ndices i e k so feitas pelas Linhas 18 a 20 usando
x como varivel auxiliar. O aspecto de sada deste programa ser,
94 17 31 50 20 73 64 84 69 59
17 20 31 50 59 64 69 73 84 94
Listagem 24
01
program ordenacao_selecao;
14
02
const
15
k := i;
16
for j := i+1 to n do
03
04
n = 10;
var
17
05
18
x := dat[i];
06
i, j, k, x: integer;
19
dat[i] := dat[k];
20
dat[k] := x;
07
begin
08
randomize;
21
end;
09
writeln;
22
writeln;
10
23
for i:= 1 to n do
11
dat[i] := random(100);
24
12
write( dat[i], #9 );
25
13
end;
26
write( dat[i], #9 );
writeln;
end.
84
t = 1+ log10( j ) (2)
j= 1
0 0 0 1
A terceira etapa, da multiplicao de um escalar d pela array data, funciona da seguinte forma. Um valor inteiro de correo ac definido e iniciado
com zero. Uma srie de produtos de d por cada clula de data ocorrem varrendo data de trs para frente. O valor de cada produto somado a ac para
obter um valor p. Este valor potencialmente contm mais de um dgito sendo o
ltimo deles aquele que deve sobrepor a clula em data multiplicada.
Linguagem de Programao I
85
ac: 0 p: 2 x 7 = 14
1 | 3 | 4
ac: 1 p: 3 x 7 = 21
1 | 1 | 4
ac: 2 p: 1 x 7 = 7
7 | 1 | 4
ac: 0
Listagem 25
01
program hiper_fatorial;
15
data[t-1] := 1;
02
var s: real;
16
for d := 2 to n do begin
03
n, t, i, d, ac, p: integer;
17
ac := 0;
04
18
05
begin
19
p := data[i] * d + ac;
06
write('Valor> ');
20
07
readln(n);
21
ac := p div 10;
08
write('Fatorial> ');
22
09
s := 1.0;
23
end;
10
for i := 1 to n do
24
for i := 0 to t-1 do
11
s := s + ln(i)/ln(10.0);
end;
25
12
t := round(s);
26
13
setlength(data, t);
27
14
write( data[i] );
writeln;
end.
O logaritmo de um nmero
a na base b, ou seja, logb
(a) , pode ser reescrito
como a razo In(a)/In(b),
onde ln o logaritmo
natural.
86
d (contador do lao) multiplicado pela array data e por essa razo ac sempre
Sntese da Parte 1
Foram apresentadas no Captulo-1 as estruturas bsicas de construo de
um programa em Pascal incluindo sintaxe bsica, utilizao de variveis e
constantes, uso de operadores e expresses, entrada e sada padres, controle de fluxo e fundamentos sobre procedimentos e funes. No Captulo-2
foram apresentadas as estruturas homogneas sequenciais da linguagem, ou
seja, strings que permitiram a representao e manipulao de informao
textual e as arrays que possibilitaram o sequenciamento de dados dos
mais diversos tipos nativos existentes.
Atividades de avaliao
1. Criar funo que receba um caractere e, caso seja uma letra, retorne sua
verso maiscula, quando a entrada for minscula, e minscula quando
a entrada for maiscula. Se a entrada no uma letra, o mesmo caractere deve ser retornado.
2. Escreva uma funo que receba uma string s e um caractere ch e retorne
o nmero de vezes que ch aparece em s.
3. Escreva programa que receba uma string da entrada padro e imprima
quantas palavras ela contm. Considere palavras como sendo pedaos
da string separados por espaos em branco.
4. Construa programa que receba uma array de inteiros e imprima como
sada o maior e o menor valor contidos nela.
Linguagem de Programao I
5. Construa programa que busque numa array os dois maiores valores contidos.
6. Construa um programa que receba uma array e altere seus valores de
forma a ficarem em ordem inversa.
7. Construir programa que carregue em uma array de comprimento n os
primeiros n valores primos.
8. Rotao o procedimento de deslocamento dos itens de uma array para
casas vizinhas. Numa rotao a direita todos os itens migram para posies logo a frente, exceto o ltimo que vai para a posio 1, ex: se v =
{1,2,3,4}, uma rotao a direita modifica v para {4,1,2,3}. De forma anloga uma rotao a esquerda de v geraria {2,3,4,1}. Construir programas
para os dois processos de rotao.
9. Construa um programa que calcule a mdia dos nmeros menores que
5000 que sejam divisveis por 7 mas no sejam divisveis por 3.
10. Considere uma array V que contenha os coeficientes de um polinmio P(x) de grau n. Construa programa que receba V, n e um valor de
x0 e imprima P(x0).
11. Seja uma lista L formada por n valores reais. Dado que:
pesos
a1 a2 a3
a4
a5
a6
a7
a8
a9
Depois se calcula a soma S1 de todos os nmeros resultantes. O dcimo dgito, d10, ser 11 (S1 mod 11),ou zero se esta conta der mais
que nove. Para calcular d11, faz-se como antes, mas leva-se em conta
tambm d10:
d1 d2 d3 d4 d5 d6 d7 d8 d9 d10
X
11
10
9
8
7
6
5
4
3
2
a1
a2
a3
a4
a5
a6
a7
a8
a9
a10
87
88
Linguagem de Programao I
Referncias
SEBESTA, Robert W., Concepts of Programming Languages, Addison
Wesley; 9 edition (April 2, 2009)
CANNEYT, Michal Van, Reference guide for Free Pascal, Document
version 2.4 , March 2010
http://www.freepascal.org/docs-html/
89
90
Parte
Tipos de Dados Personalizados
Captulo
Tipos de Dados
Personalizados
Objetivos:
Esta unidade tem por objetivo introduzir estruturas sofisticadas da linguagem Pascal. No Captulo-1 so apresentadas estruturas que permitem
abstrair e operar modelos ligados a objetos enumerveis, descritos por
campos ou associados a conjuntos. No Captulo-2 estudado o poderoso recurso dos ponteiros que tanto potencializam construes nativas do
Pascal quanto permitem um mais flexvel gerenciamento da memria do
computador. Alm das vantagens so tambm estudados os problemas
com ponteiros. Um estudo de caso prtico procura aplicar as principais
estruturas abordadas no captulo.
94
type
inteiro = integer;
o identificador inteiro passa a funcionar, aps essa definio, como o tipo primitivo integer. A declarao,
var x: inteiro;
No exemplo,
type
faixa1 = 10..20;
var
x: faixa1;
um tipo denominado faixa1 definido para que suas variveis (tais como o
exemplo x) possam representar inteiros entre 10 e 20. Atribuies explcitas
de valores fora da faixa definida (como, x := 89, neste exemplo) fazem o compilador emitir uma advertncia, mas no um erro.
O tamanho em bytes de uma varivel de tipo faixa o menor valor inteiro n tal que 28n seja maior ou igual ao total de inteiros cobertos pelo tipo.
Por exemplo na faixa 10..20, so cobertos 11 inteiros e o menor valor de n
1-byte pois 281= 28= 256> 11. Para a faixa 10..1000, que cobre 991 inteiros, n vale
2-bytes pois 282= 216= 65536> 991. Vaiveis de tipo faixa so operadas normalmente como qualquer outra variveis inteira.
Linguagem de Programao I
Tipos arrays estticas podem tambm ser definidos numa sesso type.
No exemplo,
type
O tipo tarr pode definir variveis e constantes que comportam sequencialmente dez inteiros. Nas declaraes,
const
c: tarr = (5,4,1,3,2,0,9,7,8,6);
var
x: tarr;
pode ser utilizada para inicializar x. As dez clulas de c tm o contedo copiado para as clulas de x sem necessidade de um lao. O mesmo acontece
com strings, como no exemplo,
type
mensagem = string[100];
const
erro_1: mensagem = 'disco falhou!';
var
s: mensagem;
begin
s := erro_1;
writeln(s);
end.
95
96
Listagem 26
01
02
03
04
05
06
07
08
09
program tipo_array_dinamico;
type
tdyarr = array of integer;
var
x, y: tdyarr;
i: integer;
begin
setlength(x, 20);
for i := low(x) to high(x) do x[i] := i*i;
y := x;
for i := low(x) to high(x) do y[i] := y[i]*2;
for i := low(x) to high(x) do write(x[i], );
end.
10
11
12
13
2. Enumeraes
Uma enumerao um tipo faixa especial cujos inteiros cobertos possuem
cada um seu prprio identificador. A sintaxe geral de um tipo enumerao
Pascal a seguinte,
type
Tipos enumeraes so utilizados para modelar dados que seguem algum critrio numrico de ordenao e que comummente so manipulados
por nomes prprios. Um exemplo comum so os dias da semana que podem
ser representados por variveis da enumerao seguinte,
type
Linguagem de Programao I
hoje: dia;
begin
hoje := dom;
end.
a nova sequncia de equivalentes numricos 25, 26, 27, 28, 29, 30 e 31.
Os comandos low e high, da unidade system, podem ser utilizados para
determinar os identificadores de um tipo enumerao respectivamente de me-
97
98
Linguagem de Programao I
mes: (jan, fev, mar, abr, mai, jun, jul, ago, stb, otb, nov, dez);
3. Estruturas Heterogneas
Uma estrutura heterognea em Pascal um tipo de dados construdo pelo
encapsulamnto de outros tipos de dados que podem ser nativos ou pernonalizados. O encapsulamento funciona pela definio de identificadores e seus
tipos cada qual responsvel por uma fatia dos dados que uma varivel ou
constante desta estrutura dever conter. Cada par identificador/tipo de uma
estrutura heterognea denominado campo. A sintaxe geral de um tipo estrutura heterognea em Pascal ,
type
<nome> = record
<campo_1>: <tipo_1>;
<campo_2>: <tipo_2>;
<campo_3>: <tipo_3>;
...
<campo_n>: <tipo_n>;
end;
onde a palavra reservada record (que significa registro) forma com end o bloco encapsulador de campos. O exemplo,
type
aluno = record
nome: string[25];
idade: byte;
media: real;
end;
99
100
idade e media a mdia final. A declarao de variveis de tipo estrutura heterognea segue a mesma sintaxe j apresentada. No exemplo,
var
x: aluno;
De fato, em qualquer momento do programa, os campos de uma varivel estrutura heterognea podem ser modificados ou lidos independentemente. Para imprimir em sada padro o contedo de x pode-se implementar,
writeln(Nome: , x.aluno, Idade: , x.idade, Media: , x.media:0:1);
onde o corpo contm cdigo Pascal que utiliza os campos da varivel disposta entre with e do. Estas palavras reservadas significam com e faa respectivamente. No exemplo,
with x do begin
nome := 'pedro da silva';
idade := 25;
media := 8.7;
writeln('Nome: ', aluno, ' Idade: ', idade, ' Media: ', media:0:1);
end;
Linguagem de Programao I
101
end;
erro: integer;
end;
Ponto no Plano: Os
pontos no plano cartesiano
so representados por
uma coordenada no eixo x
(abcissas) e outra no eixo
y (ordenadas).
Geometria Analtica
Plana: Parte da
matemtica que trata da
resoluo de problemas da
geometria plana atravs
do equacionamento de
entidades primitivas como
pontos, retas e cnicas.
A geometria analtica no
depende de desenhos
(apesar de ajudarem)
como a geometria plana
pura.
102
11
12
13
14
a,b,c: real;
r: root;
begin
readln(a,b,c);
r := eq2g(a,b,c);
case r.erro of
1: writeln(Polinomio invalido);
2: writeln(Raizes complexas);
end;
end.
Linguagem de Programao I
Estruturas heterogneas podem agrupar arrays, enumeraes ou mesmo outras estruturas heterogneas. No exemplo,
type estudante = record
nome: string[30];
turma: record
serie: byte;
letra: char;
end;
end;
onde x do novo tipo estudante. O campo turma de um tipo estrutura heterognea annima com trs campos por se configurar sendo o terceiro de um
tipo enumerao, tambm annimo. Usando referncias elpticas pode-se,
por exemplo, escrever,
with x.turma do begin
serie := 8;
letra := C;
turno := manha;
end;
103
104
var y: record
check: boolean;
lote: integer;
end;
Nestes casos o novo tipo fica ancorado e de uso exclusivo das variveis
definidas juntamente com ele. O acesso a campos descrito anteriormente funciona da mesma forma.
Para definir uma constante de estrutura heterognea utiliza-se a sintaxe
geral seguinte,
const
<nome>: <tipo_estrutura_heterogenea> =
(<campo1>:<valor1>;
<campo2>:<valor2>;
<campo3>:<valor3>;
...
<campon>:<valorn>);
O exemplo a seguir ilustra a definio de algumas constantes de estruturas heterogneas declaradas anteriormente,
const
um_aluno: aluno = (nome: 'pedro'; idade: 25; media: 8.5);
p: ponto = (x: 10.0; y: 30.0);
my_root: root
aplicado: estudante =
( nome: 'raul';
notas: (9.5, 10.0, 8.5, 9.4);
turma: (serie: 8; letra: 'C'; turno: manha) );
possvel definir uma array cujas clulas so de um tipo estrutura heterognea. Elas seguem a mesma sintaxe das arrays comuns. No exemplo,
var
Linguagem de Programao I
4. Conjuntos
As trs opes mais comuns de estilos de formatao de texto so o negrito,
o itlico e o sublinhado. Tais estilos podem ocorrer ao mesmo tempo, aos
pares, apenas um ou mesmo nenhum deles fazendo um total de oito possibilidades. Aos estilos de formatao denominamos de domnio de representao
do problema e s possibilidades combinatrias de conjuntos. De forma geral
um domnio com n elementos rende um total de 2n conjuntos.
A linguagem Pascal suporta a implementao de conjuntos. Um conjunto em Pascal construdo sobre um tipo inteiro, faixa ou enumerao
(denominado tipo base) e registra quaisquer uma das combinaes que os
elementos deste tipo podem formar. A sinaxe bsica de definio de um tipo
conjunto Pascal ,
type
<nome> = set of <tipo_base>;
105
106
Remoo
Verificao
Numa atribuio a varivel conjunto recebe integralmente os itens que
dever conter. Se ela contm outras informaes, estas so sobrepostas. A
sintaxe geral de uma atribuio para uma varivel conjunto ,
<variavel_conjunto> := [ <lista_de_itens> ];
caso ainda no estejam presentes, a opo negrito includa na varvel conjunto s e as opes negrito e sublinhado na varivel conjunto t.
Uma operao de remoo exclui de uma varivel conjunto um ou
mais itens se eles estiverem presentes. A construo similar a incluso, mas
substitui o operador + por -. No exemplo,
s := s - [negrito, sublinhado];
Linguagem de Programao I
possui o operador in exclusivo para verificao de itens em conjuntos. Tratase de um operador relacional posto entre o item que se deseja verificar a
presena e a varivel conjunto. Sintaticamente,
<identificador_do_item> in <conjunto>
Por exemplo, para verificar se a varivel conjunto s, de tipo estilos, contm a opo negrito, pode-se usar,
if negrito in s then
writeln(Texto em negrito!);
Atividades de avaliao
1. Construa uma estrutura heterognea que modele uma data incluindo dia,
ms e ano. Use uma enumerao para representar os meses.
2. Utilizando o modelo de data do problema-1 construa programa que leia
duas datas e diga qual delas est a frente da outra.
3. So considerados anos bissextos todos os anos mltiplos de 400 ou os
mltiplos de 4 e no mltiplos de 100. Utilizando essas informaes, uma
estrutura heterognea para datas e uma enumerao para os dias da
semana, construir programa que determine em que dia da semana cai
determinada data.
4. Utilizando estruturas heterogneas montar um modelo para nmeros
complexos e implementar funes que efetuem as operaes de soma,
subtrao, multiplicao e diviso de dois complexos dados.
5. Expandir o modelo da questo anterior e criar uma funo que retorne
razes reais ou complexas de um polinmio de segundo grau.
6. Vetores no espao possuem trs componentes referentes aos eixos x, y e
z. Construir modelo para vetor e implementar funo que retorne o mdulo
de um vetor recebido como argumento. O mdulo de um vetor calculado
pela raiz quadrada da somatria dos quadrados de suas componentes.
107
108
31
Captulo
Ponteiros
1. Fundamentos
Ponteiro um tipo de varvel utilizada para armazenar endereos de outras
variveis. Assim a informao registrada em um ponteiro um endereo de
memria. Como a forma de endereamento pode mudar entre arquiteturas
distintas, ento o contedo de um ponteiro vai depender do hardware utilizado
e do sistema operacional instalado.
Mas convenientemente, num mesmo sistema em operao, qualquer
referncia a memria feita com a mesma nomenclatura e cada varivel instanciada tem um endereo distinto. Dificilmente um programador que trabalha
com uma linguagem de alto nvel, como Pascal, ter diretamente que tratar
com valores de endereos das variveis de seus programas. Como se ver
neste captulo o uso de ponteiros quase sempre para uma operao indireta.
A ttulo de visualizao, abstraindo-se a memria como uma estrutura
linear, possvel conceber um modelo que define o endereo como a quantidade de bytes que antecede a varivel endereada (Figura - 7).
Endereo de memria
Varivel armazenada
Memria Principal
Endereo de Memria
A memria de um
computador segmentada
em agrupamentos de
clulas cujas as posies
so controladas por
valores numricos
denominados de
endereos de memria.
Eles normalmente so
representados em forma
hexadecimal (como nas
mensagens de erro do
sistema operacional). A
quantidade de bits de um
endereo de memria varia
conforme CPU e sistema
utilizados, sendo os mais
comuns os de 32-bits e
64-bits.
110
Linguagem de Programao I
Uma arquitetura cujos endereos de memria tm n-bits, pode representar um total de 2n endereos distintos. Haja vista que cada endereo refere-se a 1-byte distinto (veja Figura-4.1) ento o tamanho mximo de memria
principal gerencivel deve ser exatamente 2n-bytes. Para se ter uma ideia,
em arquiteturas populares onde n 32-bits, este total de 232 bytes, ou seja,
4-GB. Quando a memria mxima gerencivel ultrapassada no hardware, o
sistema no reconhece a memria excedente.
2. Declarao e Inicializao
de Ponteiros
Existem duas categorias de ponteiros em linguagem Pascal: os ponteiros tipados, que conhecem o tipo das variveis para onde apontam, e os no-tipados,
que no conhecem o tipo da varivel para onde apontam, mas que em contra
partida, podem apontar para variveis de quaisquer tipo.
A sintaxe para declarar um ponteiro tipado em Pascal ,
var
<ponteiro>: ^<tipo_base>;
TReg = record
x, y, z: Byte;
end;
var
reg: ^TReg;
111
112
var
pVec: ^MyVec;
MyPtInt = ^integer;
var
pp: ^MyPtInt;
Um ponteiro declarado e no inicializado pode conter um valor descontextualizado de endereo. Diz-se, neste caso, que o ponteiro armazena um
endereo no seguro. Operar endereos no seguros pode causar efeitos
colaterais de funcionamento ou mesmo suspenso de execuo do programa
(isso ocorre quando o sistema operacional se defende do uso inapropriado da
memria feito pelo programa). H trs maneiras em Pascal de inicializar um
ponteiro com um valor seguro de endereo,
Fazer o ponteiro apontar para lugar nenhum.
Atribuir diretamente ao ponteiro o endereo de uma varivel j existente.
Alocar dinamicamente um bloco de memria e deleg-lo ao ponteiro.
Analisaremos os dois primeiros tpicos nessa sesso. O terceiro tpico
ser estudado na Sesso- 4.5 .
Um ponteiro aponta para lugar nenhum quando seu contedo no conduz a uma posio real da memria. A palavra chave nil, em Pascal, utilizada
para se referir a este valor inerte de endereo. Atribuir diretamente nil a quaisquer ponteiros (tipados ou no), fazem-nos apontar para lugar nenhum. Assim,
p := nil;
Linguagem de Programao I
113
Para atribuir diretamente o endereo de uma varivel a um ponteiro, utiliza-se o operador @. Este operador determina o endereo de uma varivel qualquer
qual est pr-fixado. O resultado deve ser atribudo a um ponteiro. Exemplo,
p := @i;
Figura 8
Listagem 28
01
program PonteiroAplicado;
07
p := @i;
02
var
08
writeln(p^);
03
i: integer;
09
p^ := 231;
04
p: ^integer;
10
05
begin
06
11
end.
i := 127;
114
Um modelador um
recurso da Linguagem
Pascal que obriga um valor
de um tipo a se tornar de
outro tipo. a chamada
coero de dados. A
sintaxe de uma coero
tipo(valor) onde tipo denota
o tipo de dados para o qual
valor deve ser coagido.
i := 127;
p := @i;
q := p;
// Cpia de ponteiro
writeln(q^);
01
program PonteiroAplicado2;
02
type
03
PtInt = ^integer;
04
05
PtReal = ^real;
var
06
i: integer;
07
p, q: PtInt;
08
r: PtReal;
09
begin
10
i := 127;
11
p := @i;
12
r := PtReal(p);
13
q := PtInt(r);
14
writeln(q^);
15
end.
Linguagem de Programao I
Listagem 30
01
program PonteiroAplicado3;
08
02
type
09
i := 127;
10
p := @i;
11
q := @p;
writeln(i, ' ', p^, ' ', q^^);
03
04
PtInt = ^integer;
var
05
i: integer;
12
06
p: PtInt;
13
07
q: ^PtInt;
begin
end.
3. Ponteiros e Arrays
Se um ponteiro aponta para uma array possvel utilizar este ponteiro como se
fosse a prpria array. O operador de indexao, [], igualmente ps-fixo no ponteiro e o valor de ndice um nmero entre 0 e len-1, onde len o comprimento
do array. No h conservao dos limites de ndices adotados no array original.
Listagem 31
01
program AplicacaoPonteiro4;
02
var
03
04
pt: ^integer;
05
i: integer;
06
begin
07
pt := @arr[1];
08
for i := 0 to 4 do
09
10
115
116
program ponteiros_e_strings;
02
var
03
04
p: ^char;
05
06
p := @s[1];
07
write(p);
08
Contador de referncia
uma metodologia
utilizada para otimizar o
gerenciamento de memria
dinmica associado aos
ponteiros. Baseia-se na
definio implcita de
um contador para cada
ponteiro que armazena
o nmero de variveis
que se referem a ele.
Quando este contador zera
a memria apontada
desalocada. Dessa forma
o programador no precisa
se preocupar em desalocar
memria dinmica que
requisitou pois isso ocorre
automaticamente.
begin
end.
Linguagem de Programao I
Listagem 33
01
program uso_de_pchar;
02
var
03
p: Pchar;
04
s: string;
05
begin
06
07
writeln(p);
08
s := 'uma string';
09
p := @s[1];
10
writeln(p);
11
end.
4. Ponteiros em Mdulos
Argumentos ponteiros em mdulos, sejam procedimentos ou funes, so comumente utilizados para se referir a variveis fora do escopo do mdulo (ou
seja, variveis que no so locais ao mdulo). Esse mecanismo permite que
provisoriamente seja possvel ler ou alterar variveis alheias, sejam elas escalares ou vetoriais.
Argumentos ponteiros funcionam como quaisquer ponteiros permitindo
aritmtica e desreferenciamento clula de memria endereada. H o inconveniente entretanto de, para se declarar um argumento ponteiro em um mdulo
Pascal, necessrio definir previamente um tipo ponteiro como em,
type PtInt = ^integer;
procedure proc(q: PtInt);
Uma aplicao usual de argumentos ponteiros so os chamados argumentos sada. Ao invs do ponteiro trazer o endereo de uma varivel que se
deseja ler o valor, ele traz o endereo de uma varivel para onde se deseja
escrever um valor. Esta estratgia quebra as restries tanto da sada nica
das funes (pode-se usar vrios ponteiros cada qual associado a uma sada
diferente) quanto de ausncia de sada formal nos procedimentos (argumentos ponteiros agem como sada nos procedimentos).
117
118
Listagem 34
01 program equacao_do_segundo_grau;
02 type
03
ptreal = ^real;
04
05 function eq2g(a,b,c: real; p, q: ptreal): boolean;
06 const TOL = 1.0e-8;
07 var delta: real;
08 begin
09
10
11
eq2g := false;
12
exit;
13
end;
14
p^ := (-b + sqrt(delta))/(2*a);
15
q^ := (-b - sqrt(delta))/(2*a);
16
eq2g := true;
17 end;
18
19 var
20
a,b,c,x1,x2: real;
21 begin
22
writeln('Coeficientes: ');
23
readln(a,b,c);
24
25
26
27
28 end.
a x 2+ b x+ c= 0
onde devem ser fornecidos os coeficientes a, b e c e calculadas as razes, se
existirem. Pelo mtodo de Bskara as duas razes reais so dadas por,
Linguagem de Programao I
x=
b , onde
= b2 4 a c
2a
desde que a seja no nulo e seja no negativo (se a no nulo e negativo, as razes so complexas).
O programa da Listagem 34 resolve o problema da equao de segundo grau. A funo eq2g (das Linhas 05 a 17), que possui cinco argumentos,
recebe os trs coeficientes do polinmio de segundo grau via argumentos a,
b e c. A funo retorna trs sadas: as duas primeiras atravs dos argumentos
ponteiros p e q e a terceira via sada natural da funo (boolean). A sada booleana retrata o sucesso da operao.
Quando true retorna significa que existem razes reais e elas esto nas
clulas de memria apontadas por p e q. Quando false retorna, no h razes
(seja por porque a = 0 ou <0) e os valores apontados por p e q devem ser ignorados. O teste de nulidade de (no programa representado pela varivel delta)
consiste da expresso abs(delta)<TOL que verifica se o mdulo do valor em
delta est suficientemente prximo de zero para ser considerado como tal (este
o teste mais consistente para verificar nulidade de valores de ponto flutuante).
Quanto menor o valor da constante TOL (tolerncia) mais rigoroso ser o
teste de nulidade (na prtica valores de tolerncia demasiado pequenos so problemticos. Por exemplo, para uma tolerncia na ordem de 10-15, 0.0000000001
no passaria num teste de nulidade o que, em muitos casos, incoerente). Se
um dos testes da Linha-10 falhar o status da varivel interna eq2g mudado
para false e a funo manualmente encerrada (exit, Linha-12).
Do contrrio as razes so calculadas e, por desreferenciamento, registradas nas clulas apontadas por p e q (Linhas 14 e 15). Antes do encerramento da funo, eq2g (varivel interna) mudada para true (Linha-16) indicando que razes foram calculadas com xito.
A chamada de eq2g no programa principal acontece dentro de uma estrutura de deciso (Linha-24) ilustrando como possvel tomar diretamente uma
deciso a partir da sada de uma funo. Quando qualquer um dos blocos da
deciso bidirecional for executado (Linhas 25 ou 27), eq2g j ter sido executada.
A chamada a eq2g repassa como dois ltimos parmetros os endereos das variveis globais x1 e x2 que ao final portaro as razes, se existirem.
Uma importante habilidade que ponteiros permitem a mdulos o acesso a arrays fora de escopo (no locais). Para estruturar isso, repassa-se ao
mdulo o endereo da primeira clula do vetor (que pode ser ou no tipado) e
um inteiro que represente o comprimento da array ou a memria em bytes que
ela ocupa. Estando isso disponvel nos parmetros do mdulo, o acesso s
119
120
a funo Max recebe, atravs do ponteiro vec, o endereo da primeira clula de uma array cujo comprimento repassado por len. Esta funo deve
retornar o maior valor contido na array endereada por vec. O programa da
Listagem 35 contextualiza a funo Max. Nesta funo a primeira hiptese
de retorno o primeiro elemento da array (Linha-09). O lao da Linha-10,
associado ao teste aninhado na Linha-11, faz a varivel local Max ser atualizada constantemente para o maior valor at a iterao corrente. Com o
encerramento do lao Max conter o valor procurado. No programa principal,
a array global x carregada com valores aleatrios ao mesmo tempo em que
impresso na tela (Linhas 20 a 23). A chamada a Max efetuada de dentro
do writeln (Linha-25) sendo os argumentos o endereo da primeira clula de x
(@x[1]) e seu comprimento (length(x)). Um exemplo de sada do programa ,
23 82 50 49 81 90 80 73 17 32 79 45 86 56 39 89 57 49 1 26
Valor mximo = 90
Linguagem de Programao I
Listagem 35
01
program extremos;
02
03
type
04
PtReal = ^real;
05
06
07
var i: integer;
08
begin
09
Max := vec[0];
10
11
if vec[i]>Max then
12
Max := vec[i];
13
end;
14
15
var
16
x: array[1..20] of real;
17
18
i: integer;
begin
19
randomize;
20
21
x[i] := random(100);
22
write(x[i]:0:0, );
23
end;
24
writeln;
25
26
end.
5. Alocao Dinmica
Novas variveis podem ser criadas em tempo de execuo atravs do mecanismo de alocao dinmica. Estas variveis no possuem nomes e dependem de ponteiros para serem manipuladas. Ponteiros tipados possuem em
Pascal duas abordagens de alocao, a escalar e a vetorial, que so estudadas nas Sesses 5.1 e 5.2 . A alocao com ponteiros no tipados estudada
Sesso 5.3 .
121
122
program Alocacao_Dinamica_1;
02
var
03
i: integer;
04
p: ^integer;
05
begin
06
i := 120;
07
new(p);
08
p^:= i;
09
i := i div 2;
10
writeln(i, , p^);
11
dispose(p);
12
end.
Na Linha-13 dispose, que tambm recebe um ponteiro como argumento, libera a memria alocada por new.
Listagem - 37
01
program Alocacao_dinamica_2;
08
02
type
09
new(q);
10
q^.x := 3.0;
11
q^.y := 1.0;
12
q^.z := 0.5;
13
dispose(q);
03
ponto = record
04
x,y,z: real;
05
06
07
end;
var
q: ^ponto;
14
begin
end.
Linguagem de Programao I
As mesmas regras se mantm para variveis de tipo estrutura heterognea. O operador de resoluo de campo (.) mantm a mesma sintaxe. A
Listagem 37 ilustra a alocao escalar com tipo estrutura heterognea. Neste
programa o tipo record precisa ser definido (Linha-03) para que possa atuar
como tipo base na declarao do ponteiro q (Linha-07). Cada campo do record precisa de seu prprio desreferenciamento (Linhas 10, 11 e 12).
ou ainda,
<ponteiro> := getmem(<memria_em_bytes>);
aloca um bloco de memria que compota dez inteiros e atribui para pt o endereo.
O comando freemem similar a dispose contendo como argumento
nico o ponteiro para a rea de memria que deve ser liberada. No exemplo,
freemem(pt);
program Alocacao_Dinamica_3;
var
i, j, n: integer;
p, q: ^integer;
begin
write('Total: ');
read(n);
i := 0;
j := 0;
getmem(p, sizeof(integer)*n);
q := p;
14
q^ := i;
15
q := q + sizeof(integer);
16
inc(j);
17
18
19
20
21
22
23
24
25
end;
inc(i);
end;
q := p + i * sizeof(integer);
write(q^, ' ');
end;
freemem(p);
end.
123
124
O programa da Listagem 38 ilustra o uso de getmem e freemem. O programa imprime em ordem decrescente os primeiros n inteiros (n fornecido pelo
usurio) que so divisveis por 3 mas no so divisveis por 7. Para armazenar
estes valores alocado, na Linha-10, o espao necessrio em heap.
Para acessar individualmente cada uma das n clulas que compe o bloco, utiliza-se um ponteiro auxiliar q. H dois contextos de uso de q no programa:
o da Linha-15, engajado na inicializao da array e o da Linha-21, utilizado na
impresso dos dados.
Os comandos inc e
dec, unidade system,
fazem respectivamente
a incrementao e
decrementao numrica
de variveis ordinais
(inteiros, caracteres e
enumeraes). Estes
comandos possuem
verses de um e dois
argumentos. Na verso
de um argumento o
total incrementado (ou
decrementado) um. Na
verso de dois argumentos
este valor corresponde
ao segundo argumento.
Assim, se x contm 3, as
chamadas inc(x) e dec(x)
fazem x mudar para 4 e
2 e as chamadas inc(x,3)
e dec(x,2) para 6 e 1
respectivamente.
Figura 9
O operador de indexao, [], pode ser usado com ponteiros tipados que
apontam para vetores dinmicos. O resultado exatamente a mesma sintaxe
de arrays estticas. Por exemplo,
q := p + sizeof(integer)*i;
q^ := 21;
equivalente a,
p[i] := 21;
Essa sintaxe dispensa o uso na varivel auxiliar.
Linguagem de Programao I
Listagem 39
01
program Alocacao_Dinamica_4;
11
02
var
12
03
i, j, n: integer;
13
p[j] := i;
04
p: ^integer;
14
inc(j);
05
15
end;
06
begin
write('Total: ');
16
inc(i);
07
read(n);
17
end;
08
i := 0;
18
09
j := 0;
19
freemem(p);
10
getmem(p, sizeof(integer)*n);
20
end.
125
126
Listagem 40
01 program Alocacao_Dinamica_5;
02 type
03
04 var
05
vec: ^IntVec;
06
i: integer;
07 const
08
max = 10;
09 begin
10
11
vec^[0] := 1;
12
vec^[1] := 1;
13
for i := 2 to max-1 do
14
15
16
17
freemem(vec);
18 end.
Linguagem de Programao I
127
Listagem 41
01
02
var i: longint;
03
b: ^byte;
04
begin
05
06
b := p + i;
07
b^ := 0;
08
end;
09
end;
Se x uma varivel real e precisa ter os bytes zerados pelo procedimento zerar, deve-se escrever,
zerar(@x, sizeof(real));
Se y for uma varivel de uma estrutura heterognea chamada Reg, seus bytes
podem ser zerados com,
zerar(@y, sizeof(Reg));
Se vec for uma array de inteiros que precisa ter os bytes zerados ento deve-se escrever,
zerar( @vec[1], sizeof(integer)*length(vec) );
o bloco alocado via p recebe os valores 1000.0, 500.0, 333.4, 250.0 40.0.
Aritmtica de Ponteiros:
termo utilizado para se
referir s operaes
de soma e subtrao
de ponteiros com
deslocamentos de
memria (medidos em
bytes). Esta aritmtica
no prev operaes
entre ponteiros por ser
incoerente. Seu grande
objetivo referenciar
corretamente clulas de
memria vizinhas a uma
clula dada.
128
// Coero
for i := 0 to 24 do
q[i] := 1000/(i+1);
Linguagem de Programao I
129
Listagem 42
01 program Vazamento_de_Memoria;
02 var
03
p: ^integer;
04
i: integer;
05 begin
06
new(p);
07
p := @i;
08
dispose(p);
09 end.
Figura 10
Lista Encadeada
Elementar: uma lista
de objetos, denominados
nodos, cujo tipo
corresponde a um tipo
estruturado heterogneo
contendo um campo da
chave e outro de ponteiro
do prprio tipo estrutura
heterognea em questo.
Isso permite que o primeiro
nodo da lista contenha
uma chave e o endereo
para o segundo nodo que
contm outra chave e o
endereo para o terceiro
nodo e assim por diante.
O ltimo nodo da lista
aquele que contm uma
chave e um endereo para
parte alguma.
130
pnodo = ^nodo;
nodo = record
chave: integer;
prox: pnodo;
end;
Observe a necessidade de definio de um tipo ponteiro de nodo antes da definio da prpria estrutura. Isso levanta duas questes. A primeira
para que? e a segunda como possvel?. A resposta da primeira pela
necessidade de definio de prox que conter uma referncia ao prximo
nodo da lista e dinamicamente isso deve ser feito via um endereo de nodo.
A segunda na realidade uma nova faceta do Pascal. Apesar de ser apenas
definido na linha seguinte, o tipo nodo pode sim ser utilizado para definir pnodo. Esse fenmeno conhecido como declarao prematura e exclusiva
dos tipos ponteiros.
Para definir a lista propriamente dita propomos um outro tipo estrutura
heterognea denominado lista como segue,
lista = record
raiz: pnodo;
total: integer;
end;
plista = ^lista;
Este novo tipo mantm um ponteiro raiz para o primeiro nodo da lista
e o total de nodos listados. Apesar de no serem visveis diretamente nessa
estrutura, os demais nodos estaro presentes pois o primeiro aponta para o
segundo, que aponta para o terceiro e assim sucessivamente. O tipo plista
necessrio para possibilitar a mdulos afetarem uma lista que recebam como
argumento. Por exemplo para inicializar uma lista deve-se utilizar o procedimento,
procedure Init(Q: plista);
begin
Q^.raiz := nil;
Q^.total := 0;
end;
init zera uma lista tanto em nodos quanto em contagem. Pode ser chamado
assim,
Linguagem de Programao I
var
L: lista;
begin
init(@L);
...
Para inserir uma nova chave numa lista prope-se o seguinte algoritmo:
(i) constri-se dinamicamente um novo nodo contendo a chave de insero; (ii)
Faz-se o prox desse novo nodo apontar para o primeiro nodo da lista, ou seja,
raiz, (iii) faz-se raiz da lista apontar para este nodo e (iv) incrementar o campo
total da lista em uma unidade para indicar que um novo nodo foi inserido.
Assim a ltima chave inserida sempre a primeira da lista e a proporo
que novas chaves so inseridas as mais antigas vo ficando mais distantes de
raiz. O procedimento da Listagem 43 implementa a insero. A lista repassada via ponteiro Q e a chave de insero via inteiro x. As etapas so marcadas
como comentrios.
Listagem 43
01
02
var p: pnodo;
03
begin
04
new(p);
05
p^.chave := x;
06
p^.prox := Q^.raiz;
// (ii)
07
Q^.raiz := p;
// (iii)
08
inc(Q^.total);
09
// (i)
// (iv)
end;
Para imprimir em sada padro o contedo de uma lista deve-se varr-la desde o nodo raiz at o ltimo nodo (aquele cujo prox vale nil). Para tanto
utiliza-se um ponteiro auxiliar de pnodo e um lao pr-teste. O procedimento
imprimir na Listagem 44 Implementa o processo. O ponteiro auxiliar p inicializado com o valor de raiz da lista apontada por Q (Linha-04). O lao na
Linha-05 verifica se o final da lista j foi alcanado ao passo que a atribuio
na Linha-07 provoca um salto de um nodo para outro. Cada nodo visitado por
p tem a chave impressa na Linha-06.
Para eliminar toda uma lista encadeada elementar da memria propomos o seguinte algoritmo: (i) Se o campo raiz diferente de nil ento siga para
o passo ii, do contrrio termine; (ii) Fazer uma cpia do endereo em raiz
num ponteiro auxiliar de pnodo; (iii) Fazer prox de raiz se tornar o novo raiz;
(iv) aplicar dispose no ponteiro auxiliar e voltar para i. A Listagem 45 ilustra o
131
132
processo e os passos so marcados como comentrios. A Linha-09 adicionalmente zera o campo de contagem de nodos trazendo a lista ao estado inicial
de vazia.
Listagem 44
01
02
var p: pnodo;
03
begin
04
p := Q^.raiz;
05
06
07
p := p^.prox;
08
09
end;
end;
Listagem 45
01
02
var p: pnodo;
03
begin
04
// i
05
p := Q^.raiz;
// ii
06
Q^.raiz := p^.prox;
// iii
07
dispose(p);
// iv
08
end;
09
Q^.total := 0;
10
end;
Sntese da Parte 2
No Captulo - 3 foi tanto apresentada a sintaxe bsica de definio de
tipos personalizados quanto as estruturas nativas do Pascal que permitem a
modelagem de objetos enumerados (enumeraes), de objetos segmentados
por campos (estruturas heterogneas) e objetos agrupveis (conjuntos). No
Captulo - 4 foram introduzidos e contextualizados os ponteiros. Foram apresentadas que relaes eles mantm com outras construes da linguagem
como arrays e mdulos assim como a importante participao que exercem
no mbito da alocao dinmica de memria. Problemas com ponteiros so
tambm abordados. O captulo encerra com o estudo de caso da lista encadeada elementar.
Linguagem de Programao I
Atividades de avaliao
1. Reescreva o programa da Listagem-4.7 de forma que seja possvel, com
as informaes de sada, saber o tipo de problema que inviabilizou o clculo das razes, quando esse for o caso.
2. Construir mdulo que inverta a sequncia dos caracteres de uma string
(use Pchar).
3. Construa mdulo que receba um vetor e retorne o maior e menor valor
existente.
4. Construa mdulo que receba um vetor e retorne os dois maiores valores
existentes.
5. Escrever duas verses de programa, uma utilizando arrays dinmicas e
outra utilizando alocao dinmica, para resolver o problema de receber
uma quantidade arbitrria de notas de alunos (esta quantidade de notas
tambm entrada) e determine o valor do desvio padro da amostra. O desvio padro de uma amostra x 1 , x 2 , x 3 , ... , x n dada por,
onde x i se refere a i-sima nota e
6. Seja P um ponteiro que aponta para um bloco de memria alocado dinamicamente. Se P precisar apontar para um bloco de memria maior, sem
perder as informaes para as quais j aponta, deve-se: (I) alocar o novo
espao, maior que o anterior; (II) copiar todo contedo do bloco apontado
por P para a nova memria alocada; (III) desalocar o espao apontado
por P; (IV) apontar P para a nova memria alocada. O processo de cpia
deve ser de tal forma que independa do tipo de informao apontada.
Construir mdulo com este fim e contextualiz-lo num programa.
7. Crie uma estrutura vector (usando estruturas heterogneas) que mantenha dois campos: um ponteiro de real data e um inteiro n. O campo data
refere-se a um vetor de real cujo comprimento o valor do campo n.
Construa tambm mdulos que permitam as seguintes operaes com
variveis de tipo vector: (a) construtor (recebe um comprimento qualquer
e retorna um vector novo com tal comprimento e com todos os elementos
de data iguais a zero); (b) valor modular (retorna raiz quadrada da somatria dos quadrados dos elementos de data); (c) normalizador (modifica
um vector de forma que todos os elementos em data sejam divididos
pelo valor modular); (d) destrutor (recebe um vector, desaloca a memria
apontada por data e zera seu comprimento).
133
134
Referncias
CANNEYT, Michal Van, Reference guide for Free Pascal, Document
version 2.4 , March 2010
http://www.freepascal.org/docs-html/
http://en.wikipedia.org/wiki/Tower_of_Hanoi
Parte
Modularizao
Captulo
Modularizao
Objetivos:
A modularizao, estudada no Captulo-1 desta unidade, uma tcnica
que permite a segmentao de um programa em unidades menores mais
fceis de gerenciar. So as funes e os procedimentos. Para estud-la
com mais detalhes o captulo aborda noes sobre controle e processo
bem como um estudo mais aprofundado sobre o mecanismo de passagem de argumentos introduzido no Captulo-1. O captulo ainda cobre
outros importantes conceitos relacionados como a recursividade e o aninhamento modular. O Captulo-2 finaliza a unidade apresentado os recursos que o Pascal disponibiliza para a manipulao de arquivos. Isso inclui
desde fundamentos sobre o funcionamento da memria secundria at
recursos e comandos que permitiro a implementao de programas que
manipulem arquivos.
O Compartilhamento de
Tempo ou Time Sharing
um recurso das CPUs
modernas que surgiu pela
necessidade de execuo
concorrente de vrias
aplicaes. Sistemas
que tiram proveiro deste
recurso so denominados
Sistemas Multitarefas
138
O compartilhamento de tempo entre processos ocorre de forma similar dentro de cada processo onde tarefas internas competem pelo tempo
de CPU(s) da aplicao. Estes subprocessos competindo entre si so denominados threads. Se mais de um thread est envolvido diz-se tratar-se
uma aplicao multithreading.
Cada thread (caso mais de um esteja envolvido) segue um fluxo de
execuo que comea num programa principal e pode ser desviado para um
mdulo (funo ou procedimento). Dessa forma apenas um dado mdulo (ou
o programa principal), num thread, executa por vez. Diz-se neste contexto que
aquele mdulo (ou o programa principal) possui o controle do fluxo. Quando
ocorre desvio de controle, ou seja, um mdulo chamado, este passa a possuir o controle e o chamador deve aguardar sua finalizao para resgat-lo de
volta. Um programa termina sua execuo quando o controle, que est com o
programa principal, retornado ao sistema operacional.
Os programas em Pascal estudados neste livro executam sobre um
nico thread de forma que o fluxo de controle est exatamente com foco num
nico mdulo (ou no programa principal) num dado instante da execuo.
Os comandos round, trunc,
frac e int, unidade system,
so comandos utilizados
para operar nmeros
reais. Todos possuem
apenas um argumento de
entrada. Round e trunc
retornam respectivamente
o arrendondamento e o
piso do valor de entrada,
ambos inteiros. Frac
retorna a parte fracionria
da entrada, tambm real e
Int retorna uma verso real
da parte inteira da entrada.
Os exemplos round(4.8),
trunc(4.8), Frac(4.8)
e Int(4.8) devolvem
respectivamente 5, 4, 0.8
e 4.0.
O controle de uma funo ou procedimento pode foradamente ser devolvido ao seu chamador, ou seja, antes do trmino da execuo completa de
seu cdigo. O comando exit, unidade system, efetua esta tarefa. Por exemplo,
no procedimento,
procedure print(n: integer);
begin
n = n div 3;
end;
end;
quando valores negativos so repassados o procedimento chama exit devolvendo imediatamente o controle ao chamador. Do contrrio uma sequencia
de valores impressa por ao da execuo do lao while.
Como visto anteriormente, funes possuem uma varivel interna com
mesmo nome da funo e cujo valor antes da devoluo de controle ao chamador justamente seu retorno. Assim a presena de um exit numa funo
estratgica quando o valor de retorno j foi determinado, mas o final da funo
ainda no foi alcanado (linha contendo o ltimo end; da funo) . No exemplo,
Linguagem de Programao I
139
caso a entrada seja um valor negativo, ento a funo deve retornar imediatamente ao chamador com retorno zero. Para implementar esse comportamento
associou-se uma estrutura de deciso (que verifica a possvel negatividade de
n), uma atribuio direta do valor 0 a fnc (varivel interna) e uma chamada a exit.
Um programa tambm pode devolver diretamente o controle ao sistema
operacional independendo do mdulo que esteja executando. Isso representa
matar o programa e em Pascal conseguido com uma chamada ao comando
halt, unidade system.
140
Neste caso o 6 inteiro convertido para um valor real. Se for porm a situao
seguinte,
teste(5.0, 6.0);
causar um erro de compilao porque 5.0 (que real) no pode ser transformado em inteiro diretamente. Estas situaes caracterizam a coero em
Pascal. Coagir um valor significa transform-lo noutro tipo. A coero pode ser
de estreitamento ou de alargamento. No estreitamento o tipo final do valor
menos expressivo (possui menor memria ou representa faixas mais restritas
de valores) e por isso pode ocorrer perda de dados. Exemplos so, de real
para integer, de longint para char, extended para real e etc. No alargamento
ocorre exatamente o inverso e logo no h perda de dados.
Em Pascal a coero de alargamento entre parmetros reais e formais normalmente aceita pelo compilador desde que haja compatibilidade.
Entretanto a coero de estreitamento frequentemente reporta um erro. A rigor
as restries de coero tambm ocorrem em atribuies explcitas como,
x := y;
se x e y forem de tipos distintos ou for necessria uma coero de estreitamento, o compilador reportar um erro de converso.
A passagem de valores entre parmetros formais e reais conhecida
como atribuio implcita.
Linguagem de Programao I
type
ptint = ^integer;
procedure inc(q: ptint);
begin
q^:= q^ + 1;
end;
o argumento formal q recebe o endereo de um inteiro que est fora do procedimento inc e, por desreferenciamento, permite mudar a clula de memria
apontada (neste exemplo aumenta de uma unidade o inteiro com endereo
em q). Em Pascal necessrio antes predefinir o tipo ponteiro (uso de type)
antes de utiliz-lo como tipo de um argumento formal (neste exemplo ptint
definido previamente). Como o argumento real precisa ser um endereo, ento uma chamada vlida a inc ,
x := 56;
// x inteiro
inc(@x);
write(x);
// 57
Neste caso como deve ser repassado uma array de inteiros, ento o primeiro
argumento um ponteiro de inteiro (ir receber o endereo para o primeiro
inteiro da array). O comprimento da array deve ser repassada como segundo
argumento (por valor) e as clulas individuais podero ser acessadas pelo
operador ps-fixo [] (os valores de ndice esto entre 0 e len-1). Para usar a
funo max deve-se repassar naturalmente o endereo da primeira clula de
uma array de inteiros existente como,
141
142
var
data: array[1..10] of integer;
x: integer;
begin
{...}
x := max(@data[1], 10);
{...}
O efeito o uso da passagem por endereo, mas sem necessidade de fornecer o comprimento ou usar operadores de ponteiros. A Listagem 46 Ilustra
o uso deste recurso. Na Linha-03, data no uma array dinmica mas sim
um ponteiro para uma array. Seu uso similar entretanto a uma array dinmica incluindo ndice limite inferior igual a zero (Linha-06). A array definida na
Linha-12 repassada a max (Linha-14) sem o uso dos operadores @ e [].
Listagem 46
01
program maximo;
02
03
04
var k: integer;
05
begin
06
max := data[0];
07
08
09
10
11
const
12
13
14
15
writeln( max(arr) );
// 88
end.
Linguagem de Programao I
O procedimento dobrar duplica o valor que est armazenado no parmetro formal x. Como x uma referncia, a operao ter efeito sobre o
parmetro real que for repassado numa chamada a dobrar. Exemplo,
var
q: integer;
begin
q := 26;
dobrar(q);
writeln(q);
// 52
end.
pode-se abstrair que a, b e c so argumentos de entrada e que x um argumento de sada. Em geral o valor que x contm na entrada do mdulo no
importante, mas seu estado final, antes do retorno do controle, representa o
valor de sada. No programa da Listagem 47 a funo eq2g recebe trs argumentos por valor (coeficientes de um polinmio de segundo grau) e gera trs
sadas: duas atravs dos argumentos (referncias) x1 e x2 (razes do polinmio) e uma terceira sada natural da funo (booleano). Semanticamente a
funo tenta calcular as razes e coloc-las em x1 e x2.
143
144
program equacao_do_segundo_grau;
02
03
04
05
begin
06
07
08
eq2g := false;
09
exit;
10
end;
11
x1 := ( -b + sqrt(delta) )/(2*a);
12
x2 := ( -b - sqrt(delta) )/(2*a);
13
eq2g := true;
14
end;
15
16
var
17
c: array[1..3] of real;
18
p, q: real;
19
begin
20
write('Coeficientes: ');
21
22
23
24
else
25
26
Linguagem de Programao I
145
4. Recursividade
A recursividade um recurso de linguagem que permite um mdulo, seja
ele funo ou procedimento, fazer uma chamada de si mesmo, ou seja,
dentro do corpo de cdigo do mdulo possvel fazer uma ou mais chamadas daquele mdulo. A recursividade permite implementaes mais
claras de diversos algoritmos e por essa razo um recurso nativo do
Pascal. Para calcular, por exemplo, o fatorial de um inteiro pode-se usar
a seguinte funo,
function fat(n: integer): integer;
begin
if n<2 then
fat := 1
else
fat := n * fat(n-1);
end;
Nesta funo o identificador fat, sem qualquer cdigo ps-fixado, representa a varivel interna cujo valor antes da finalizao da funo seu valor de
retorno. O mesmo identificador com os parnteses ps-fixados, fat(n-1), possui semntica diferente e representa uma chamada recursiva ao mdulo fat.
Observe que o argumento desta chamada o valor de entrada n decrescido
de uma unidade e logo o retorno da funo deve ser n multiplicado pelo fatorial
de n-1.
Este retorno entretanto no pode devolver imediatamente o controle ao
chamador porque depende do retorno da chamada a fat(n-1). Por sua vez esta
chamada causar outra chamada, desta vez a fat(n-2), e esta a fat(n-3) e assim
por diante. Cada vez que uma nova chamada realizada a fat, uma nova verso da funo empilhada em memria sobre aquela que a chamou gerando
uma cadeia de dependncias de retorno.
O processo de empilhamento de funes seria infinito no fosse a condio de parada implementada nas duas primeiras linhas de cdigo do corpo de
fat. O if obriga que entradas menores que 2 retornem imediatamente o valor 1
(o fatorial de 0 e 1 de fato 1, mas o fatorial de valores negativos no existe, por
isso cautela no uso desta funo).
Assim quando o empilhamento alcanar valores menores que 2, nenhuma nova chamada recursiva ser realizada e comear um processo, de trs
para a frente (em relao a ordem das chamadas recursivas) de resolues de
retornos at que a chamada original seja alcanada. A sequncia de operaes
a seguir descreve o clculo do fatorial de 5 pela funo fat,
146
Fat(5)
// 1 chamada pendente
5 * fat(4)
// 2 chamadas pendentes
5 * 4 * fat(4)
// 3 chamadas pendentes
5 * 4 * 3 * fat(2)
// 4 chamadas pendentes
// 4 chamadas pendentes
5 * 4 * 3 * 2
// 3 chamadas pendentes
5 * 4 * 6
// 2 chamadas pendentes
5 * 24
// 1 chamada pendente
120 // resolvido
Linguagem de Programao I
Listagem 48
01
program torre_de_hanoi;
02
03
04
begin
05
if n = 0 then exit;
06
hanoi(n-1, A, C, B);
07
08
hanoi(n-1, C, B, A);
09
end;
10
11
begin
12
13
147
148
5. Aninhamento Modular
Em Pascal possvel construir um mdulo (funo ou procedimento) dentro
do corpo de outro mdulo. Este recurso conhecido como aninhamento modular e os mdulos aninhados de mdulos internos. No exemplo,
procedure teste;
function soma(a,b: integer): integer;
begin
return a+b;
end;
begin
write( soma(3, 8) );
end;
Linguagem de Programao I
Listagem 49
01
program busca_binaria;
02
03
04
05
06
begin
07
rbusca := -1;
08
09
10
if L[med] = x then
11
rbusca := med
12
13
14
else
15
16
17
end;
begin
18
19
20
21
const
22
23
24
25
26
x := busca_bin(M, 11);
27
if x > 0 then
28
29
writeln(x)
else
30
31
writeln('nao encontrado');
end.
149
150
6. Unidades
A sada gerada pelo compilador quando recebe como entrada um arquivo
de cdigo de um programa um arquivo binrio executvel. Ele representa
o cdigo de mquina que pode ser executado diretamente em hardware e
ao mesmo tempo est atrelado a servies do sistema operacional sobre o
qual se procedeu a compilao. Se sesses de clusula uses esto presentes, ento o compilador acessar e anexar recursos de outros arquivos que
so binrios mas que no so executveis. Em Pascal estes arquivos so
denominados unidades e so tambm provenientes de outros processos de
compilao mas a estrutura bsica de implementao diferente.
A estrutura bsica para implementao de uma unidade Pascal a seguinte,
unit <nome_da_unidade>;
<recursos>
interface
<interfaces>
implementation
<implementaes>
end.
Linguagem de Programao I
interface
procedure ola;
implementation
procedure ola;
begin
write('OLA');
end;
procedure tchau;
begin
write('TCHAU');
end;
end.
151
152
existem dois procedimentos implementados, mas apenas um deles est atalhado na sesso de interface. Dessa forma a compilao do programa,
program novo;
uses teste;
begin
ola;
tchau;
end;
A compilao de um arquivo fonte de unidade tem como sada dois arquivos com mesmo nome da entrada mas com extenses diferentes, em geral
.o e .ppu. O arquivo de extenso .o o arquivo objeto (que surge tambm na
compilao de programas) e representa uma ponte entre o arquivo de cdigo
fonte e o arquivo binrio final de extenso .ppu. Mesmo havendo no mesmo diretrio do projeto o arquivo de cdigo de unidade .pas, o arquivo binrio .ppu
que o compilador requer quando uma clusula uses precisa ser resolvida em
outra parte do projeto. Assim se o .pas de uma unidade modificado, ele precisa ser recompilado ou do contrrio o .ppu antigo ser utilizado. Em projetos
assistidos por uma IDE, normalmente uma compilao resolve os problemas
de recompilao de unidades que tiveram seus cdigos modificados.
Linguagem de Programao I
A Listagem 50 mostra a implementao da unidade ncomplex que permite representar e operar nmeros complexos (soma, subtrao, multiplicao e diviso). Na interface ficam a definio do tipo de dados complex, que
representa um nmero complexo (re representa a parte real e im a imaginria)
alm dos prottipos das operaes bsicas. Apenas a funo conj, Linha-39,
no possui interface.
Listagem 50
Ainda na Listagem 50, o procedimento init inicializa um nmero complexo, que recebe por referncia no primeiro argumento, com os valores
de seus dois ltimos argumentos. As funes soma, subt, mult e quoc retornam um novo complexo respectivamente igual a soma, subtrao, mul-
153
154
program teste_complexos; 07
print( soma(a,b) );
02
uses ncomplex;
08
print( subt(a,b) );
03
var a, b: complex;
09
print( mult(a,b) );
04
begin
10
05
init(a, 3, 2);
06
11
print( quoc(a,b) );
end.
O programa da Listagem 51 ilustra o uso da unidade ncomplex imprimindo o resultado das quatro operaes bsicas implementadas para dois
complexos dados. A sada obtida ,
(1.0,8.0)
(5.0,-4.0)
(-18.0,14.0)
(0.2,-0.6)
Atividades de avaliao
1. Se uma array for passada por referncia a um mdulo, ele poder modific-lo. Utilizando este recurso implemente uma funo capaz receber e
ordenar uma array de comprimento qualquer.
2. Implemente uma verso de resoluo do problema da Torre de Hani utilizando quatro pinos (um origem, um destino e dois auxiliares) de forma
a diminuir, para uma mesma quantidade de discos dada, o nmero de
movimentaes.
3. Implementar uma verso no recursiva (iterativa) para a busca binria.
4. A sequncia de Fibonacci uma srie infinita de nmeros naturais cujos
dois primeiros termos so 1 e os demais so calculados pela soma dos
dois termos anteriores. Os seis primeiros termos da sequncia so ento
1, 1, 2, 3, 5 e 8. Criar duas verses de procedimentos, uma iterativa e
outra recursiva, que imprimam os n primeiros termos da sequncia de
Fibonacci, onde n um argumento de entrada.
Linguagem de Programao I
de
2k+k 1 .
k= 0
155
Captulo
61
Arquivos
1. Memria Secundria
Executar um programa significa processar sequencialmente suas instrues
de mquina. Este processo requer no apenas uma CPU de processamento
eficiente, mas tambm de memria onde possam ser armazenadas e buscadas rapidamente as instrues. a chamada memria principal. A performance desta memria justificada pela associao de duas caractersticas:
o acesso aleatrio e a volatilidade. O acesso aleatrio a capacidade que o
hardware possui de permitir que qualquer clula de memria seja acessada
num tempo constante e muito pequeno. A volatilidade refere-se a condio
de presena de corrente eltrica no dispositivo para que alguma informao
esteja presente.
Memria Secundria um termo utilizado para se referir a qualquer
dispositivo que almeje o armazenamento no voltil de informaes (estaro
registradas mesmo aps o desligamento do dispositivo). De forma geral, devido a diferena funcional, existe maior quantidade de memria secundria
em relao a primria (que tambm mais cara). A memria secundria
representada por dispositivos como discos rgidos, pendrivers e cartes de
memria (de cmeras digitais, celulares e etc).
O gerenciamento de memria principal e secundria pelo sistema operacional feita de forma distinta. A disposio dos programas em execuo
na memria principal no diretamente visvel ao usurio que apenas pode
obter informaes gerais como o total de memria utilizado. No caso da memria secundria toda informao visualizvel em forma de uma rvore de
diretrios e arquivos.
Um arquivo tecnicamente uma sequencia de bytes com nome prprio, tamanho definido e endereo exclusivo (veja Figura - 10). Um diretrio ou
pasta um continer de arquivos e tambm de outras pastas (por isso a hierarquia de dados em memria secundria anloga a uma rvore). A primeira
158
Partio Lgica
possvel aos sistemas
operacionais atuais definir
que parte, por exemplo,
de um disco ser utilizada.
Na prtica, uma vez
estabelecido isso, todas
as operaes de leitura
e gravao de arquivos
ocorrero nessa parte. No
existe uma barreira fsica
de acesso ao restante do
disco e por essa razo dizse que o particionamento
lgico.
Memria
Arquivo
Endereo do incio do arquivo
H dispositivos de memria secundria de acesso aleatrio e de acesso sequencial. Nos dispositivos de acesso aleatrio, como os discos rgidos, o
tempo de acesso a blocos fundamentais de bytes ocorre num tempo aproximadamente constante definido pelo fabricante, mas que ir variar de modelo para
modelo. Nos dispositivos de acesso sequencial, como as fitas magnticas, o
tempo de acesso a blocos fundamentais de bytes muda consideravelmente.
Nestes dispositivos uma agulha magnetizada de leitura fica fixa enquanto dois rolos, compartilhando uma mesma fita magntica (como num cassete)
giram levando ou trazendo a fita conforme a posio que ela deva ficar sob a
Linguagem de Programao I
159
2. Fluxos
Em Pascal os arquivos so classificados em binrios e de texto. Um arquivo
binrio aquele gerado pela concatenao de dados provenientes diretamente da memria principal e sem processamento adicional (isso significa que o
arquivo contm uma imagem do que esteve em memria). Arquivos binrios
podem ser tipados e no tipados. Um arquivo binrio tipado aquele formado
pela concatenao de dados binrios de mesmo tipo e tamanho denominados
de registros de arquivo.
Um arquivo de dados no tipado concatena dados binrios no necessariamente de mesmo tipo ou tamanho. Um arquivo texto aquele constitudo
exclusivamente por caracteres visveis (da tabela ASCII) e comummente representam algum tipo de documentao. Eles requerem processamento adicional para serem gerados, ou seja, os dados em memria, que precisam ser
gravados num arquivo texto, precisam ser primeiramente transformados do
Salvar um documento,
uma imagem, uma
planinha, um desenho
e etc, utilizando uma
aplicao especializada,
constitui uma tarefa de
descarregamento forado
da memria principal para
a secundria.
160
F: file;
F: file of <tipo_base>;
onde file of so palavras reversavas que significam arquivo de. O tipo base
define o tipo comum dos dados concatenados no arquivo. No exemplo,
var
F: file of integer;
var
<manipulador>: text;
T: text;
O primeiro argumento uma referncia a um fluxo que deve ser vinculado a um arquivo cujo nome o segundo argumento. Um nome de arquivo em
geral segue as regras de endereamento de arquivos do sistema operacional
onde o programa compilado. Se o arquivo aberto ou criado na mesma pasta do binrio executvel, no necessrio detalhar o endereo com hierarquia
de pastas, como em,
Linguagem de Programao I
assign(F, teste.dat);
// Linux
000110010111101111001000000011100011011101010100
000110010111101111001000000011100011011101010100
000110010111101111001000000011100011011101010100
000110010111101111001000000011100011011101010100
Incio do Arquivo
(Posio zero)
Posio dois
Posio trs
Final do Arquivo
no Linux ou,
assign('.\data\teste.dat');
//Windows
3. Modos de Acesso
Depois da vinculao, o passo seguinte definir o modo de acesso do arquivo. O modo de um arquivo define basicamente o suporte s operaes de
leitura (verificao dos dados que ele contm) e escrita (adio de novos dados ou modificao de dados j existentes). O modo de um arquivo tambm
define a sua chamada posio corrente que equivale a um ponto de entrada
de uma nova operao de leitura ou escrita no arquivo.
A posio corrente representada por uma medida em registros entre o
incio do arquivo e o ponto de operao. Assim, por exemplo, a posio zero
indica que zero registros precedem a posio corrente (incio do arquivo). Na
Figura-6.2 uma seta ilustra a posio corrente em quatro pontos distintos de
um mesmo arquivo cujos registros possuem um byte cada.
H trs modos de acesso de arquivos em Pascal,
Modo de Escrita
Modo de Leitura
Modo de Anexao
161
162
No modo de escrita, para fluxos de texto, ser permitida apenas a gravao de dados. Para fluxos binrios ser possvel leitura e gravao. Neste
modo, se o arquivo ainda no existir, ele logicamente criado em memria
secundria. Se ele j existir ento seu contedo sumariamente apagado
antes das novas operaes de escrita. Assim o processamento inicia sempre
com um arquivo de tamanho zero (bytes). Para definir um arquivo em modo de
escrita usa-se o comando rewrite que recebe como argumento nico o fluxo
que deve configurar. Exemplo,
assign(F, teste.dat);
rewrite(F);
...
Linguagem de Programao I
Nem sempre possvel abrir um arquivo. Quando este for o caso ento um erro em tempo de execuo ocorrer e o programa ser suspenso.
Utilizando a diretiva {$I-}, antes do cdigo de abertura do arquivo, possvel
desligar a emisso explcita do erro e manter a execuo. O custo desta desabilitao a necessidade de checar manualmente se ocorreu silenciosamente um erro e impedir que ele cause outros erros mais adiante.
Essa checagem manual feita com a funo IOResult que retorna o
status da ltima operao executada pelo sistema de manipulao de arquivos. Se IOResult retornar zero, nenhum erro ter ocorrido. Do contrrio o valor
de retorno, que um inteiro, corresponder ao cdigo de um erro. A Tabela-6.1
lista os possveis cdigos de erros de sada de IOResult e seus respectivos
significados. Para religar a emisso de erros usa-se a diretiva {$I+}.
Tabela 1
163
164
Listagem 52
01
02
var F : file;
03
begin
04
{$I-}
05
06
reset (F);
07
{$I+}
08
09
close(F);
10
end;
Para fechar um fluxo aberto (e descarregar o ltimo contedo em memria principal) usa-se o comando close com sintaxe,
close(<fluxo>);
Linguagem de Programao I
var
F: file;
begin
assign(F, 'teste.dat');
remove(F);
end.
165
166
Listagem 53
01 program arquivo_de_inteiros;
02 var
03
f: file of integer;
04
i: integer;
05 begin
06
assign(f, 'teste.dat');
07
rewrite(f);
08
randomize;
09
for i := 1 to 100 do
10
write(f, random(100));
11
close(f);
12 end.
Os comandos ramdomize
e random, unidade system,
so utilizados para gerar
nmeros pseudo aleatrios
em Pascal. ramdomize
um procedimento sem
argumentos que deve ser
chamado uma nica vez
antes de chamadas futuras
a random para possibilitar
o mximo de aleatoriedade
possvel. As chamadas
a random requerem um
ou nenhum argumento e
retornam nmeros pseudo
aleatrios. Quando no h
argumento o valor pseudo
aleatrio gerado real e
est entre 0.0 e 1.0. Se o
argumento existe, ele deve
ser um inteiro n e a sada
gerada um inteiro entre 0
e n-1.
Para verificar ou modificar manualmente a posio corrente de um arquivo, a unidade system dispe os comandos a seguir,
eof
filepos
seek
Linguagem de Programao I
Listagem 54
01
program lendo_arquivo_de_inteiros;
08
02
var
09
read(f, i);
write(i, ' ');
03
f: file of integer;
10
04
i: integer;
11
end;
12
close(f);
05
begin
06
assign(f, 'teste.dat');
07
reset(f);
13 end.
Quando a posio corrente de um arquivo binrio no est no fim do arquivo ento uma operao de escrita causa uma sobreposio como ilustrado
na Figura 11. Por exemplo, para substituir o quadragsimo inteiro do arquivo
gerado pelo programa da Listagem 53 usa-se,
seek(F, 39);
write(F, 123);
Esta operao ir gravar o valor 123 sobre aquele que est na quadragsima posio do arquivo com fluxo F. O tamanho do arquivo no modificado e a posio corrente final a quadragsima primeira.
167
168
Posio corrente 2
Escreveu trs bytes (sobreposio)
Posio corrente agora 5
Figura 11
Listagem 55
01
02
03
04
tmp, a: integer;
begin
05
assign(F, fnome);
06
reset(F);
07
seek(F, pos);
08
read(F, tmp);
09
seek(F, pos);
10
write(F, x);
11
12
read(F, a);
13
seek(F, filepos(F)-1);
14
write(F, tmp);
15
tmp := a;
16
end;
17
write(F, tmp);
18
close(F);
19
end;
Caso seja necessrio inserir dados no meio do arquivo ento o comportamento padro de sobreposio no ser desejvel. Uma forma de resolver o
problema proposta pela funo na Listagem 55. Os argumentos de entrada
so o nome do arquivo, lido pela string fnome, o valor da posio onde deve
haver a insero, lido pelo inteiro pos e o item de insero lido pelo inteiro x
(supe-se um arquivo binrio de inteiros). O primeiro passo abrir o arquivo
em modo de leitura (Linhas 05 e 06) e Ir para a posio onde deve ocorrer a
insero do novo registro (Linha-07).
Em seguida faz-se uma cpia do registro nesta posio em tmp
(Linha-08) e retorna-se a posio de insero (a leitura causou avano da
Linguagem de Programao I
tmp
tmp
tmp
tmp
Figura 12
Observe que a expresso filesize(F)-3 calcula a posio no arquivo vinculado a F do terceiro inteiro contado de trs para frente. A chamada seguinte
truncate elimina os trs inteiros reduzindo o arquivo.
A eliminao de registros internos a um arquivo binrio requer que eles
primeiramente sejam movidos para o final do arquivo antes da truncagem
(veja esquema na Figura 13). Para movimentar um registro indesejado para o
169
170
final do arquivo deve-se efetuar sucessivas trocas entre ele e o registro logo
esquerda. Isso deslocar tal registro em direo ao final do arquivo ao mesmo tempo que trar em uma posio para trs todos os demais registros que
inicialmente se encontravam a sua frente. Na Figura 14 o registro indesejado
possui valor 9. Aps seis trocas ele atinge a ltima posio, onde eliminado.
Movimentao de dados
para o fim do arquivo
Truncamento
Figura 13
2 7 9 1 3 6 4 7 1
2 7 1 9 3 6 4 7 1
2 7 1 3 9 6 4 7 1
2 7 1 3 6 9 4 7 1
2 7 1 3 6 4 9 7 1
2 7 1 3 6 4 7 9 1
2 7 1 3 6 4 7 1 9
2 7 1 3 6 4 7 1
Figura 14
Listagem 56
01 procedure remover(fnome: string; pos: integer);
09
read(F, a, b);
10
seek(F, filepos(F)-2);
03
11
write(F, b, a);
04 begin
12
seek(F, filepos(F)-1);
05
assign(F, fnome);
13
end;
06
reset(F);
14
truncate(F);
07
seek(F, pos);
15
close(F);
08
16
a, b: integer;
end;
Linguagem de Programao I
O procedimento da Listagem 56 implementa a movimentao com remoo de um registro interno a um arquivo binrio de inteiros. Os argumentos de
entrada so o nome do arquivo (fnome) e a posio onde se localiza o registro
indesejado (pos). Primeiramente o arquivo vinculado ao fluxo F e a posio
corrente mudada para a do registro indesejado (Linhas 05, 06 e 07). O lao entre as Linhas 08 e 13 efetua as trocas dos registros vizinhos.
Para tanto so lidos de cada vez dois registros usando as variveis a e
b (Linha-09). Em seguida regride-se duas posies para trs (Linha-10) e, por
sobreposio, grava-se b e a nesta ordem (Linha-11) (troca propriamente dita).
Para que na iterao seguinte a nova troca possa ocorrer corretamente, deve-se regredir uma posio para trs (Linha-12).
O teste de continuao do lao na Linha-08 verifica se a posio corrente
do arquivo atingiu a penltima posio haja vista que so lidos dois registros
de cada vez. O uso de eof neste caso causaria uma tentativa de leitura alm
do fim do arquivo. Quando o lao se encerra a posio corrente ter atingido o
ltimo registro que por sua vez possuir o valor indesejado. O truncamento na
Linha-14 elimina o ltimo registro do arquivo.
Todas as operaes descritas nessa sesso se estendem a quaisquer
tipos base que definam um fluxo. No seguinte exemplo,
type
aluno = record
nome: string[25];
idade: byte;
media_final: real;
end;
var
G: file of aluno;
171
172
Linguagem de Programao I
Observe que o ponto (.) tambm entra na contagem do total de caracteres da string e por essa razo entre | e 3 existe apenas um caractere
em branco.
Para formatar uma string em write/writeln usa-se a notao s:n onde s
define uma string e n o total de caracteres que a string final deve possuir. Se
o valor em n for maior que o comprimento de s, haver preenchimento com
caracteres em branco esquerda. No exemplo,
x := carro;
writeln(|, x:10, |);
Ola mundo!!
writeln insere adicionalmente um caractere de nova linha. Assim uma anexao futura (uso de append) ocorrer na linha seguinte do arquivo. Por exemplo
a execuo de,
assign(F, 'saida.txt');
append(F);
writeln(F, x:5, q:12:5, 'Ola mundo!!':20);
close(F);
173
174
0.27200
Ola mundo!!
123
0.27200
Ola mundo!!
program Alunos;
02
03
04
05
var F: text;
06
begin
07
{$I-}
08
assign(F, fnome);
09
reset(F);
10
{$I+}
11
if ioResult=0 then
12
append(F)
13
else
14
rewrite(F);
15
16
17
18
var s: string;
19
i: byte;
20
m: real;
21
ch: char;
22
begin
23
repeat
24
write('Nome> ');
25
26
27
inserir('aluno.txt', s, i, m);
28
writeln('continuar S/N?');
29
readln(ch);
30
31
readln(s);
Linguagem de Programao I
O programa da Listagem 57 ilustra a insero de dados num arquivo texto chamado aluno.txt. Cada linha do arquivo deve conter sequencialmente o nome de aluno, sua idade e sua mdia final. A insero dos
dados de um novo aluno feita pelo procedimento inserir que recebe
como argumentos o nome do arquivo base de insero (argumento fnome), o nome do aluno (argumento nome), a idade (argumento idade) e a
mdia final (argumento media).
Na primeira parte do procedimento testada a existncia do arquivo base (Linhas 06 a 09). Caso ele exista, aberto em modo de
anexao (Linha-11) seno ele criado (Linha-13). A insero de dados propriamente dita ocorre na Linha-14 e o fechamento do arquivo na
Linha-15.
O programa principal mantm um lao entre as Linhas 23 e 30
que requisita constantemente por dados de novos alunos e os insere em
aluno.txt (Linha-27). Cada chamada repassa o nome deste arquivo e os
dados do novo aluno, abre o arquivo, grava e por fim o fecha.
No final de cada insero o usurio tem a opo de parar ou continuar dependendo do valor que fornecer a ch (Linhas 29 e 30). Um aspecto de aluno.txt aps algumas inseres listado a seguir,
joao da silva 25
9.5
8.0
9.0
7.0
8.7
5.6
alfedro pacheco 29
7.8
175
176
var F: text;
linha: string;
begin
{$I-}
assign(F, 'aluno.txt');
reset(F);
{$I+}
if ioResult=0 then
while not seekeof(F) do begin
readln(F, linha);
writeln(linha);
end;
close(F);
end;
Linguagem de Programao I
Sntese da Parte 3
No Captulo 1 foi estudada a modularizao que incluiu noes sobre controle de execuo em um processo monothread, aspectos sobre a passagem de argumentos em procedimentos e funes, noes
sobre uso e aplicaes da recursividade, a importncia do aninhamento modular e por fim a compilao de mdulos afins numa unidade Pascal. No Captulo 2 foi estudado o sistema padro de manipulao de arquivos da Linguagem Pascal incluindo a noo de
fluxo de informaes entre memria principal e secundria. Os principais comandos desde sistema foram apresentados convenientemente em suas respectivas categorias (dos arquivos binrio e de texto)
e adicionalmente exemplificados para melhor fixar suas funcionalidades.
Atividades de avaliao
1. Construir programa que gere um arquivo binrio contendo 1000 inteiros
aleatrios entre 200 e 5000.
2. Construir programa que crie um arquivo contendo apenas inteiros pares
oriundos de um arquivo gerado pelo programa da questo anterior.
3. Construir programa que crie uma cpia de um arquivo dado, mas com
nome distinto.
4. Construir programa que leia um arquivo gerado pelo programa do problema-1 e inverta sua sequencia original de inteiros.
5. Uma estrutura heterognea chamado ponto mantm dois campos, x e y,
que representam uma coordenada no plano. Utilizando este tipo de dados, construir programa que crie um arquivo binrio contendo 200 pontos
da funo f(x) = 5x3 - 7x com x no intervalo [5, 50]. Escolha valores de x
equidistantes.
6. Construir programa que leia o arquivo gerado na questo anterior e crie
uma verso texto dele.
7. O procedimento da Listagem-6.5 ilustra como movimentar um registro para o fim do arquivo e depois elimin-lo por truncamento.
Reconstruir o procedimento de forma que seja possvel movimentar
177
178
Referncias
CANNEYT , Michal Van, Reference guide for Free Pascal, Document
version 2.4 , March 2010
http://www.freepascal.org/docs-html/
Linguagem de Programao I
Sobre o autor
Ricardo Reis Pereira: Possui graduao em Engenharia Mecnica pela
Universidade Federal do Cear (2000) e mestrado em Programa de Mestrado
em Enganha ria Qumica pela Universidade Federal do Cear (2004).
Atualmente professor assistente do curso Sistemas de Informao do
Campus de Quixad da Universidade Federal do Cear. Ministra as disciplinas de fundamentos de programao, clculo diferencial e integral, estruturas
de dados e computao grfica e atua nas reas de algoritmos, computao
grfica e mais recentemente em viso computacional.
179