Sign in Join
Wiki copytemporary

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.

Revision 1, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.