Você está na página 1de 6

 

 
 
 

Módulo 7 ‐ Conceito de Estruturas dinâmicas. 
As variáveis em Pascal são criadas na memória. São definidas no programa principal (código) e quando se 
executa o programa elas vão ocupar o seu espaço no segmento de dados da memória RAM. O que podemos 
concluir é que o espaço ocupado pelos dados em memória não aumenta ao longo da execução do programa. 
Exemplo: 

Se definirmos uma estrutura tipo array 

Var nomes:array[1..5] of string; 

Esta estrutura de dados irá ocupar 256x5 bytes em memória visto que cada string ocupa 256 bytes. Se na 
altura da execução do programa pretendermos aumentar o nº de strings não podemos. 

 Podemos resolver este problema utilizando estruturas dinâmicas de memória, em que não definimos um 
tamanho específico para a estrutura mas vamos pedindo memória ao Sistema Operativo de acordo com as 
necessidades. Obviamente não vamos trabalhar com as variáveis do tipo array, mas sim utilizando ponteiros 
que são variáveis  que identificam zonas de memória que pedimos ao S.O. (Sistema Operativo). Portanto no 
programa principal vamos definir alguns ponteiros ou um ponteiro para uma estrutura de dados tipo registo 
(record) e no programa em execução cada vez que precisamos de mais memória pede‐se ao S. O. Essa 
memória e guarda‐se o endereço de memória num ponteiro. 

O Ponteiro passa a ser o equivalente a um espécie de “pega” para a zona de dados em memória, assim como 
uma variável tem o seu nome que também é uma “pega” para uma zona de dados, só que trabalham de 
maneira distinta os ponteiros trabalham com memória dinâmica e as variáveis são memórias estáticas, isto é,  

Memória Estática são as variáveis que estão definidas durante o programa inteiro estão na zona de 
dados do programa, não aumentam nem diminuem. Olimite de utilização desta memória são 64Kbytes que é 
o tamanho do segmento de dados. 

Memória Dinâmica, são zonas de dados que ao longo da execução do programa são pedidas ao Sistema 
Operativo e cujo endereço armazenamos em ponteiros. A memória dinâmica tem como limite de utilização a 
capacidade de memória do computador que pode ascender a 1Gbyte ou mais. 

Declaração de Ponteiros. 
Um ponteiro é uma variável que vai conter um endereço de uma zona de memória que corresponde a um 
tipo de dado concreto. Por exemplo podemos definir um ponteiro para um byte: 

Var ptr_byte:^byte; 

Esta variável poderá conter um endereço de memória de uma zona de dados do tipo BYTE, caso contrário dá 
erro! Como podemos pedir memória ao S.O. e atribuir o valor 5 à essa zona?: 

Var ptr_byte:^byte; 

 
Prof. Agostinho Andrade      11º CPIG 
 
Agrupamento Antº José de Almeida 2009/20010      pag. 1/6 
 
 
 
 
 

Begin 
Ptr_byte  Ptr($62E8,$0) 

  Getmem(ptr_byte,sizeof(byte));          Ù 
5  5 
  Ptr_byte^:=5; 

  Freemem(ptr_byte, sizeof(byte)); 

 End. 

Deste exemplo podemos retirar várias informações: O ptr_byte vai conter o valor ($62E8,$0) que é um 
endereço de memória que contém por sua vez o valor “5”, tal como foi dito o ponteiro é uma espécie de 
“etiqueta” ou “pega” para a zona de dados. Nota importante: Quando um ponteiro não aponta para 
nenhuma zona de memória ele deve conter o valor NIL, isto é a indicação de que não está a apontar para 
nenhum endereço de memória (isto é não contém nenhum endereço de memória). 

Uma outra situação que pode ser necessária é nós obtermos o endereço de uma variável e coloca‐la num 
ponteiro, para isso usamos as instrução @, que vai dar o endereço de memória onde está colocada a dita 
variável. 

Var    Aluno:byte 

          Ptr_aluno:^byte; 

Begin 
Aluno  Ptr($62E8,$0) 

  Aluno:=5;          Ù 
5  5 
  Ptr_aluno:=@aluno; 

  Writeln(Ptr_aluno^);  (* vai escrever no monitor o conteúdo da célula para onde o ptr_aluno está 

    a apontar, que neste caso é a variável aluno, logo aparece o 5 *) 

 End. 

Qual a vantagem deste tipo de utilização da memória? 
A vantagem é a quantidade de informação que podemos colocar em memória e a independência que essa 
quantidade tem na execução do programa, isto é, numa dada altura ao executar o programa poderei precisar 
de 500Kbyte de memória mas noutra poderei precisar de 4Mbyte. 

Como podemos armazenar esta informação? 
Podemos armazenar em listas de dados interligados: 

 
Prof. Agostinho Andrade      11º CPIG 
 
Agrupamento Antº José de Almeida 2009/20010      pag. 2/6 
 
 
 
 
 

 
     
 

Os dados são colocados em memória mas há um elemento de ligação que permite percorrer a lista do 
princípio ao fim. 

Quantos tipos de lista existem? 

Basicamente há dois tipo 

• A “pilha” ou “stack” em inglês, que também é chamada de LIFO (Last in first out, tradução: último a 
entrar primeiro a sair) 
 
 

O primeiro elemento a entrar foi o “A” e o 
último foi o “D”, mas o primeiro a sair será 
o “D” e o último será o “A” 

 
 
• O “fila circular” ou “buffer” em inglês, que também é chamada de FIFO (First in first out, tradução: 
primeiro a entrar primeiro a sair) 
 
 
entra  D  C  B  A  sai
 

O primeiro a entrar foi o “A” e vai ser o primeiro a sair 
 
Como podemos então armazenar dados e fazer as ligações entre eles? 
Vamos necessariamente usar registos (records) para criar um TYPE em Pascal que possa armazenar 
os dados que entendemos e os ponteiros para fazer a ligação: 
 
type 
 ptrTficha=^tficha; 
 tficha=record 
         ptr_seguinte:ptrTficha; 
         numero:byte; 
       end; 
 
var ptr_ficha:ptrTficha; 
 
 
Prof. Agostinho Andrade      11º CPIG 
 
Agrupamento Antº José de Almeida 2009/20010      pag. 3/6 
 
 
 
 
 

Neste exemplo temos a definição de um TYPE ponteiro para um record que vai conter por sua vez 
um ponteiro para este novo type que definimos (isto para fazer a ligação entre elementos da lista) e 
a zona de dados que neste caso é um byte. Como podemos ver só vamos fazer a ligação para o 
próximo elemento da lista, isto quer dizer que não podemos andar para trás, só para a frente 
portanto estamos perante um lista unidireccional. 
Depois de definirmos um type, vamos declarar uma variável ponteiro para esse type, essa variável é 
quanto basta para começarmos a fazer a nossa lista, pois o seguinte elemento será endereço de 
memória que estiver na ligação do próximo (ptr_seguinte) e assim sucessivamente até que o 
ptr_seguinte=NIL, situação que marca o fim da lista. 
Ver os programas executados nas aulas sobre a ligação e utilização das listas unidirecionais. 
 
 
Quantos tipos de listas existem? 
Há dois tipos de listas: 
• a unidireccional onde apenas temos um ponteiro de ligação e apenas percorremos a lista num só 
sentido. Normalmente devemos sempre guardar o endereço da extremidade por exemplo o início: 
ex: 
type 
 ptrTficha=^tficha; 
 tficha=record 
         ptr_seguinte:ptrTficha; 
         numero:byte; 
       end; 
 
var ptr_ficha, ptr_inicio, ptr_actual:ptrTficha; 
       opcao:char; 
       num:byte; 
 
begin 
 ptr_inicio:=NIL; 
 repeat 
  writeln(‘Introduza um valor’); 
  readln(num); 
  if ptr_inicio=NIL then 
   begin 
     getmem(ptr_ficha,sizeof(tficha));  {pedido de memória ao S. O.} 
     {depois de pedir memória, vamos edita‐la com os valores que queremos} 
     ptr_ficha^. ptr_seguinte:=NIL;  {não há próximo elemento} 
     ptr_ficha^. numero:=num;  {coloca‐se o valor na zona de memória} 
     ptr_inicio:=ptr_ficha;  {vamos copiar o enderço para o ptr_inicio pois se trata da 1ª                      
                                                       ficha que estamos a inserir na lista} 
   
   end 
 
Prof. Agostinho Andrade      11º CPIG 
 
Agrupamento Antº José de Almeida 2009/20010      pag. 4/6 
 
 
 
 
 

  else 
   begin 
     getmem(ptr_ficha,sizeof(tficha));  {pedido de memória ao S. O.} 
     {depois de pedir memória, vamos edita‐la com os valores que queremos} 
     ptr_ficha^. ptr_seguinte:=NIL;  {não há próximo elemento} 
     ptr_ficha^. numero:=num;  {coloca‐se o valor na zona de memória} 
     {agora vamos procurar o local onde colocar esta nova ficha que já está pronta, devemos procurar o fim da lista e 
coloca‐la a seguir} 
     ptr_actual:=ptr_inicio {começa a partir do início da lista} 
     while ptr_actua^.ptr_seguinte<>Nil do 
      ptr_actual:= ptr_actua^.ptr_seguinte; { vai fazer um ciclo que em ptr_actual vai estar a entrar sempre a 
próxima ficha até que chega ao fim da lista e para} 
       { como estamos com ptr_actual no último elemento da lista podemos actualiza‐lo para acrescentar outro elemento à 
lista} 
     ptr_actua^.ptr_seguinte:=ptr_ficha;  {já está, o ptr_actual já tem próximo} 
 
   end; 
  writeln(‘quer sair?’); 
  readln(opcao); 
 until opcao=’s’; 
 { como não precisamos mais da memória, vamos liberta‐la. Para isso temos que percorrer todos os elementos da lista e ir 
libertando um a um} 
 ptr_actual:=ptr_inicio {começa a partir do início da lista} 
 while ptr_actua^.ptr_seguinte<>Nil do 
    begin 
      ptr_ficha:=ptr_actual; { guarda o actual em ptr_ficha para poder liberta‐lo, isto é, vamos eliminar todos os 
elementos começando no início da lista e indo até ao fim, nas aulas fizemos ao contrário!} 
      ptr_actual:= ptr_actua^.ptr_seguinte; { prepara já o próximo endereço} 
      freemem(ptr_ficha,sizeof(tficha));  {liberta o endereço que está em ptr_ficha pois já temos o endereço do 
próximo em ptr_actual} 
   end; 
      freemem(ptr_actual,sizeof(tficha));  {como já não há mais nenhum element já não se entrou o ciclo While logo 
ficou apenas o elemento que estava em ptr_actual, portanto há que liberta‐lo e acabou o programa}  
end. 
 
Atenção que este exemplo nos mostra que quando pedimos memória ao S. O. Temos que liberta‐
la porque senão vamos consumindo a memória do S.O. até que o sistema pare por completo. 
• No outro tipo de lista temos as listas duplamente ligadas ou bidireccionais. Estas listas são mais 
práticas visto que podemos percorre‐las nos dois sentidos. 
type
ptrTficha=^tficha;
tficha=record
ptr_seguinte:ptrTficha;
ptr_anterior:ptrTficha;
numero:byte;
end;

 
Prof. Agostinho Andrade      11º CPIG 
 
Agrupamento Antº José de Almeida 2009/20010      pag. 5/6 
 
 
 
 
 

var ptr_ficha:ptrTficha;
 
Com estes exemplos podemos fazer armazenamento de dados em memória dinamicamente de 
quantos elementos nós desejarmos com total independência do programa principal pois só depende 
do momento de execução. 
 
Ver programas das aulas. 

 
Prof. Agostinho Andrade      11º CPIG 
 
Agrupamento Antº José de Almeida 2009/20010      pag. 6/6 
 

Você também pode gostar