Ponteiros no Pascal / Delphi - Ponteiros para estruturas (Record)

Os ponteiros podem ser usados também para indicar o endereço de uma estrutura de dados (Record em Pascal / Delphi). Basta além de definir a estrutura, também definir um ponteiro para este tipo de estrutura como no exemplo abaixo:

program Project1;
{$APPTYPE CONSOLE}

uses SysUtils;

type
  PCadastro = ^TCadastro;
  TCadastro = record
    Nome: string;
    Endereco: string;
    Idade: Integer;
  end;

var
  Cadastro: PCadastro;
begin
  New(Cadastro);
  try
    Cadastro^.Nome := ‘Alex’;
    Cadastro^.Endereco := ‘Rua X, 1′;
    Cadastro^.Idade := 35;
    WriteLn(‘Nome: ‘, Cadastro^.Nome, ‘ Endereco: ‘, Cadastro^.Endereco,
      ‘ Idade: ‘, Cadastro^.Idade);
  finally
    Dispose(Cadastro);
  end;
  ReadLn;
end.

No exemplo temos a definição de PCadastro que é um tipo ponteiro para uma estrutura TCadastro. Esta estrutura (Record) apresenta 3 campos. E definimos uma variável Cadastro do tipo PCadastro.

Quando o New é executado, é alocado na memória espaço para que caiba todos os membros de TCadastro. O mesmo New retorna na variável Cadastro o endereço de memória alocado. Assim, quando fazemos a derreferência ^, obtemos o conteúdo da memória alocada como se fosse uma variável do tipo TCadastro.

Na linguagem C, para acessar um struct (mesmo que Record) apontado por um ponteiro, podemos utilizar a seguinte sintaxe:

(*cadastro).idade = 35;

Ou ainda utilizar o operador flecha -> que já faz a derreferência:

cadastro->idade = 35;

Em Pascal / Delphi, temos o que chamamos de derreferência automática. Ou seja, quando usamos ponteiros para estruturas, pode-se omitir o operador de derrêferencia ^ para acessar os membros do Record. Quando se usa o . na frente do ponteiro, o compilador já faz internamente a derreferência. O nosso exemplo anterior pode ser reescrito da seguinte forma:

program Project1;
{$APPTYPE CONSOLE}

uses SysUtils;

type
  PCadastro = ^TCadastro;
  TCadastro = record
    Nome: string;
    Endereco: string;
    Idade: Integer;
  end;

var
  Cadastro: PCadastro;
begin
  New(Cadastro);
  try
    Cadastro.Nome := ‘Alex’;
    Cadastro.Endereco := ‘Rua X, 1′;
    Cadastro.Idade := 35;
    WriteLn(‘Nome: ‘, Cadastro.Nome, ‘ Endereco: ‘, Cadastro.Endereco,
      ‘ Idade: ‘, Cadastro.Idade);
  finally
    Dispose(Cadastro);
  end;
  ReadLn;
end.

Quando o New ocorre, ele aloca um espaço na memória, mas não a inicializa. Por causa disso, se o programador esquecer de definir algum membro da estrutura, seu conteúdo pode conter sujeira. Para evitar este tipo de transtorno, uma dica é utilizar o procedimento FillChar.

procedure FillChar(var X; Count: Integer; Value: Byte);

O FillChar, atribue o valor Value, Count vezes a partir do endereço que está alocado a variável X. Para inicializarmos endereços de memória, basta definir 0 (zero) a toda estrutura criada, no nosso exemplo bastaria escrever o seguinte código logo depois do try:

FillChar(Cadastro^, SizeOf(TCadastro), 0);

Desta forma, nem todos os membros de Cadastro precisam ser definidos.

3 Respostas para “Ponteiros no Pascal / Delphi - Ponteiros para estruturas (Record)”


  1. 1 BIA

    galera me uma luz nesse negocio ai é mto dificil pra pakas..
    aff tendo aprender e naum da, nunk da certo..
    agradeço desde de ja..

  2. 2 Alecão

    @Bia, posso te ajudar se tiver uma dúvida específica. Neste próprio blog tem o assunto do começo ao fim, veja desde o primeiro post. Veja se te ajuda.

  3. 3 Leandro C. Rodrigues

    Ola. Parabéns. Legal encontrar esse conteudo tão bem esplicado. Desculpem se esse não é o local correto para a dúvida, mas no procedimento abaixo(exemplo q vem com o delphi) é possível apontar para o ponteiro da tabela quando se seleciona um item em uma Treeview. A dúvida é quando eu tenho uma estrutura master/detail??? Alguma dica??? Valeu!
    procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
    begin
    Datasource1.enabled := Node.data nil;
    if DataSource1.enabled then Table1.gotobookmark(node.data);
    end;

Deixe uma Resposta