Compreendendo e usando ponteiros no Delphi

Mesmo que os ponteiros não sejam tão importantes em Delphi como eles estão em C ou C ++, são uma ferramenta tão "básica" que quase tudo relacionado a programação deve lidar com os ponteiros de alguma forma.

É por esse motivo que você pode ler sobre como uma string ou objeto é realmente apenas um ponteiro, ou que um manipulador de eventos como o OnClick é na verdade um ponteiro para um procedimento.

Ponteiro para o tipo de dados

Simplificando, um ponteiro é uma variável que contém o endereço de qualquer coisa na memória.

Para concretizar essa definição, lembre-se de que tudo o que é usado por um aplicativo é armazenado em algum lugar na memória do computador. Como um ponteiro contém o endereço de outra variável, é dito que aponta para essa variável.

Na maioria das vezes, os ponteiros no Delphi apontam para um tipo específico:

var
iValue, j: inteiro; pIntValue: ^ inteiro;
início
iValue: = 2001; pIntValue: = @iValue;... j: = pIntValue ^;
fim
;

o sintaxe para declarar um tipo de dados ponteiro usa um

instagram viewer
circunflexo (^). No código acima, iValue é uma variável do tipo inteiro e pIntValue é um ponteiro do tipo inteiro. Como um ponteiro não passa de um endereço na memória, devemos atribuir a ele o local (endereço) do valor armazenado na variável inteira iValue.

o @ operator retorna o endereço de uma variável (ou uma função ou procedimento como será visto abaixo). Equivalente ao operador @ é Função Addr. Observe que o valor do pIntValue não é 2001.

Nesse código de exemplo, pIntValue é um ponteiro inteiro digitado. Um bom estilo de programação é usar ponteiros digitados o máximo possível. O tipo de dados Ponteiro é um tipo genérico de ponteiro; representa um ponteiro para qualquer dado.

Observe que quando "^" aparece após uma variável de ponteiro, ele desassocia o ponteiro; ou seja, ele retorna o valor armazenado no endereço de memória mantido pelo ponteiro. Neste exemplo, a variável j tem o mesmo valor que iValue. Pode parecer que isso não tem propósito quando podemos simplesmente atribuir iValue a j, mas esse trecho de código está por trás da maioria das chamadas à API do Win.

Ponteiros NILing

Ponteiros não atribuídos são perigosos. Como os ponteiros nos permitem trabalhar diretamente com a memória do computador, se tentarmos (por engano) gravar em um local protegido na memória, poderemos obter um erro de violação de acesso. Esta é a razão pela qual devemos sempre inicializar um ponteiro para NIL.

NIL é uma constante especial que pode ser atribuída a qualquer ponteiro. Quando nada é atribuído a um ponteiro, o ponteiro não faz referência a nada. O Delphi apresenta, por exemplo, um espaço vazio matriz dinâmica ou uma sequência longa como ponteiro nulo.

Ponteiros de caracteres

Os tipos fundamentais PAnsiChar e PWideChar representam ponteiros para os valores AnsiChar e WideChar. O PChar genérico representa um ponteiro para uma variável Char.

Esses ponteiros de caracteres são usados ​​para manipular terminação nula cordas. Pense em um PChar como um ponteiro para uma cadeia terminada por nulo ou para a matriz que representa uma.

Ponteiros para registros

Quando definimos um registro ou outro tipo de dados, é uma prática comum também definir um ponteiro para esse tipo. Isso facilita a manipulação de instâncias do tipo sem copiar grandes blocos de memória.

A capacidade de ter ponteiros para registros (e matrizes) facilita muito a configuração de estruturas de dados complicadas como listas e árvores vinculadas.

tipo
pNextItem = ^ TLinkedListItem
TLinkedListItem = registrosName: String; iValue: Inteiro; NextItem: pNextItem;
fim
;

A idéia por trás das listas vinculadas é nos dar a possibilidade de armazenar o endereço no próximo item vinculado em uma lista dentro de um campo de registro NextItem.

Ponteiros para registros também podem ser usados ​​ao armazenar dados personalizados para cada item da exibição em árvore, por exemplo.

Indicadores de procedimento e método

Outro conceito importante de ponteiro no Delphi são os ponteiros de procedimento e método.

Os ponteiros que apontam para o endereço de um procedimento ou função são chamados de ponteiros procedimentais. Ponteiros de método são semelhantes aos ponteiros de procedimento. No entanto, em vez de apontar para procedimentos independentes, eles devem apontar para métodos de classe.

Ponteiro de método é um ponteiro que contém informações sobre o nome e o objeto que está sendo chamado.

Ponteiros e API do Windows

O uso mais comum para ponteiros no Delphi é a interface com o código C e C ++, que inclui o acesso à API do Windows.

janelas As funções da API usam vários tipos de dados que podem não ser familiares para o programador Delphi. A maioria dos parâmetros na chamada de funções da API são ponteiros para algum tipo de dados. Como declarado acima, usamos cadeias terminadas em nulo no Delphi ao chamar funções da API do Windows.

Em muitos casos, quando uma chamada de API retorna um valor em um buffer ou ponteiro para uma estrutura de dados, esses buffers e estruturas de dados devem ser alocados pelo aplicativo antes que a chamada da API seja feita. A função API do Windows SHBrowseForFolder é um exemplo.

Alocação de ponteiro e memória

O poder real dos ponteiros vem da capacidade de reservar memória enquanto o programa está sendo executado.

Esse trecho de código deve ser suficiente para provar que trabalhar com ponteiros não é tão difícil quanto parece à primeira vista. É usado para alterar o texto (legenda) do controle com o identificador fornecido.

procedimento GetTextFromHandle (hWND: THandle);
var
pTexto: PChar; // um ponteiro para char (veja acima)TextLen: inteiro;
início

{obtenha o tamanho do texto}
TextLen: = GetWindowTextLength (hWND);
{alocar memória}

GetMem (pText, TextLen); // pega um ponteiro
{obtenha o texto do controle}
GetWindowText (hWND, pText, TextLen + 1);
{exibe o texto}
ShowMessage (String (pText))
{liberte a memória}
FreeMem (pText);
fim
;
instagram story viewer