Копия викизеркало

Это зеркало вики с pascal.chat. Правка, история и вход — там.

Pointer/ru

Deutsch · English · Français · Suomi · Русский

Тип Pointer в Free Pascal имеет два значения:

Общее представление

Pointer представляет собой переменную, которая содержит адрес памяти локальной или глобальной переменной, а также адрес памяти сложного объекта, который был создан и сохранен в области динамической памяти программы, называемой "куча". Можно сказать, что это ссылка на значение/переменную или "указатель на" значение/переменную. Для некоторых типов данных указатель может быть объявлен с помощью оператора ^ перед названием этого типа. С помощью установки рекомендуемой директивы компилятора {$TYPEDADDRESS ON} указатели могут хранить адреса переменных или значений только тех типов данных, на которые они были объявлены.

Адрес переменной присваивается указателю с помощью оператора @. Выделение памяти и присваивание адреса для значения/объекта, размещенного в куче осуществляется с помощью процедуры New. Чтение и запись данных по указателю, "ссылающегося на" переменную, возможно с помощью оператора разыменования ^, который записывается сразу после указателя.

pascal
program test_pointer_wiki2;
{$TYPEDADDRESS ON}
var 
  a         : Integer = 100;
  b         : Real = 10.5;
  ptrToInt  : PInteger;  // PInteger - указатель на целое, объявленный в библиотеке RTL,
                         // который может ссылаться только на значение/переменную типа Integer
  ptrToInt2 : ^Integer;  // общий вид объявления указателя
begin
  //ptrToInt := @b;      // возникнет ошибка компиляции с установленной директивой {$TYPEDADDRESS ON} 
  ptrToInt := @a;        
  //Writeln(ptrToInt);   // компилятор выдаст ошибку: Error: Can't read or write variables of this type
  Writeln(ptrToInt^);    // выведет 100
  New(ptrToInt2);        // выделение памяти в куче для типа Integer
  Writeln(ptrToInt2^);   // выведет случайное целое число
  ptrToInt2^ := 222;     // присваивание значения выделенной памяти целого типа
  Writeln(ptrToInt2^)    // выведет 222 
end.

Тип данных

Тип данных Pointer - это просто тип, который может содержать адрес переменной или значения любого типа данных. В этом заключается противоположность между указателями типа Pointer и типизированными указателями на переменные (например указатели типа PInteger), которые могут ссылаться только на переменные или значения конкретных типов при использовании директивы компилятора {$TYPEDADDRESS ON}. Например:

pascal
{$TYPEDADRESS ON} 
Var 
  a : Integer = 20;
  b : Real = 20.5;
  c : Boolean = true;
  ptr : Pointer;
begin
  ptr := @a; // корректное хранение адреса переменной типа Integer 
  ptr := @b; // корректное хранение адреса переменной типа Real
  ptr := @c  // корректное хранение адреса переменной типа Boolean
end.

Но, прежде чем использовать переменную типа Pointer она должна быть

  1. приведена к типу значения или переменной, на которую она ссылается
  2. разыменована с помощью оператора ^

Например:

pascal
Var 
  a      : Integer = 20;
  ptr    : Pointer;
begin
  ptr := @a;          // корректное хранение адреса переменной типа Integer 
  //Writeln(ptr);     // некорректно - не будет скомпилировано
                      // Error: Can't read or write variables of this type
  //Writeln( ptr^);   // Error: Can't read or write variables of this type
                      // Недостаточно просто разыменовать переменную типа Pointer
  Writeln( PInteger(ptr)^); // После приведения типа и разыменования указателя: выведет 20
end.

Предопределенные типы указателей

В модуле System стандартной библиотеки RTL объявлен ряд указателей для встроенных типов переменных, включающий следующие типы:

pascal
  PSmallInt           = ^Smallint;
  PShortInt           = ^Shortint;
  PInteger            = ^Integer;
  PByte               = ^Byte;
  PWord               = ^word;
  PDWord              = ^DWord;
  PLongWord           = ^LongWord;
  PLongint            = ^Longint;
  PCardinal           = ^Cardinal;
  PQWord              = ^QWord;
  PBoolean            = ^Boolean;

См. также:


From the Free Pascal wiki, page "Pointer/ru", as it stood on 2020-02-23 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Версия 1, последнее изменение: WikiArchive, .