Pointer/ru: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Pointer/ru
| Old | New | Line | |
|---|---|---|---|
| 1 | + | Тип **Pointer** в Free Pascal имеет два значения: | |
| 2 | + | ||
| 3 | + | - термин или понятие для целого класса типов и переменных этих типов | |
| 4 | + | - просто тип данных, который может хранить адрес переменной любого другого типа | |
| 5 | + | ||
| 6 | + | ## Общее представление | |
| 7 | + | ||
| 8 | + | **Pointer** представляет собой переменную, которая содержит адрес памяти локальной или глобальной переменной, а также адрес памяти сложного объекта, который был создан и сохранен в области динамической памяти программы, называемой "куча". Можно сказать, что это [[Reference/ru|ссылка]] на значение/переменную или "указатель на" значение/переменную. Для некоторых типов данных указатель может быть объявлен с помощью оператора **^** перед названием этого типа. С помощью установки рекомендуемой директивы компилятора *{\$TYPEDADDRESS ON}* указатели могут хранить адреса переменных или значений только тех типов данных, на которые они были объявлены. | |
| 9 | + | ||
| 10 | + | Адрес переменной присваивается указателю с помощью оператора **[[@/ru|@]]**. Выделение памяти и присваивание адреса для значения/объекта, размещенного в куче осуществляется с помощью процедуры **New**. Чтение и запись данных по указателю, "ссылающегося на" переменную, возможно с помощью оператора разыменования **^**, который записывается сразу после указателя. | |
| 11 | + | ||
| 12 | + | ``` pascal | |
| 13 | + | program test_pointer_wiki2; | |
| 14 | + | {$TYPEDADDRESS ON} | |
| 15 | + | var | |
| 16 | + | a : Integer = 100; | |
| 17 | + | b : Real = 10.5; | |
| 18 | + | ptrToInt : PInteger; // PInteger - указатель на целое, объявленный в библиотеке RTL, | |
| 19 | + | // который может ссылаться только на значение/переменную типа Integer | |
| 20 | + | ptrToInt2 : ^Integer; // общий вид объявления указателя | |
| 21 | + | begin | |
| 22 | + | //ptrToInt := @b; // возникнет ошибка компиляции с установленной директивой {$TYPEDADDRESS ON} | |
| 23 | + | ptrToInt := @a; | |
| 24 | + | //Writeln(ptrToInt); // компилятор выдаст ошибку: Error: Can't read or write variables of this type | |
| 25 | + | Writeln(ptrToInt^); // выведет 100 | |
| 26 | + | New(ptrToInt2); // выделение памяти в куче для типа Integer | |
| 27 | + | Writeln(ptrToInt2^); // выведет случайное целое число | |
| 28 | + | ptrToInt2^ := 222; // присваивание значения выделенной памяти целого типа | |
| 29 | + | Writeln(ptrToInt2^) // выведет 222 | |
| 30 | + | end. | |
| 31 | + | ``` | |
| 32 | + | ||
| 33 | + | ## Тип данных | |
| 34 | + | ||
| 35 | + | Тип данных **Pointer** - это просто тип, который может содержать адрес переменной или значения **любого** типа данных. В этом заключается противоположность между указателями типа Pointer и типизированными указателями на переменные (например указатели типа PInteger), которые могут ссылаться только на переменные или значения конкретных типов при использовании директивы компилятора {\$TYPEDADDRESS ON}. Например: | |
| 36 | + | ||
| 37 | + | ``` pascal | |
| 38 | + | {$TYPEDADRESS ON} | |
| 39 | + | Var | |
| 40 | + | a : Integer = 20; | |
| 41 | + | b : Real = 20.5; | |
| 42 | + | c : Boolean = true; | |
| 43 | + | ptr : Pointer; | |
| 44 | + | begin | |
| 45 | + | ptr := @a; // корректное хранение адреса переменной типа Integer | |
| 46 | + | ptr := @b; // корректное хранение адреса переменной типа Real | |
| 47 | + | ptr := @c // корректное хранение адреса переменной типа Boolean | |
| 48 | + | end. | |
| 49 | + | ``` | |
| 50 | + | ||
| 51 | + | Но, прежде чем использовать переменную типа Pointer она должна быть | |
| 52 | + | ||
| 53 | + | 1. приведена к типу значения или переменной, на которую она ссылается | |
| 54 | + | 2. разыменована с помощью оператора **^** | |
| 55 | + | ||
| 56 | + | Например: | |
| 57 | + | ||
| 58 | + | ``` pascal | |
| 59 | + | Var | |
| 60 | + | a : Integer = 20; | |
| 61 | + | ptr : Pointer; | |
| 62 | + | begin | |
| 63 | + | ptr := @a; // корректное хранение адреса переменной типа Integer | |
| 64 | + | //Writeln(ptr); // некорректно - не будет скомпилировано | |
| 65 | + | // Error: Can't read or write variables of this type | |
| 66 | + | //Writeln( ptr^); // Error: Can't read or write variables of this type | |
| 67 | + | // Недостаточно просто разыменовать переменную типа Pointer | |
| 68 | + | Writeln( PInteger(ptr)^); // После приведения типа и разыменования указателя: выведет 20 | |
| 69 | + | end. | |
| 70 | + | ``` | |
| 71 | + | ||
| 72 | + | ## Предопределенные типы указателей | |
| 73 | + | ||
| 74 | + | В [[System unit/ru|модуле System]] стандартной [[RTL/ru|библиотеки RTL]] объявлен ряд указателей для встроенных типов переменных, включающий следующие типы: | |
| 75 | + | ||
| 76 | + | ``` pascal | |
| 77 | + | PSmallInt = ^Smallint; | |
| 78 | + | PShortInt = ^Shortint; | |
| 79 | + | PInteger = ^Integer; | |
| 80 | + | PByte = ^Byte; | |
| 81 | + | PWord = ^word; | |
| 82 | + | PDWord = ^DWord; | |
| 83 | + | PLongWord = ^LongWord; | |
| 84 | + | PLongint = ^Longint; | |
| 85 | + | PCardinal = ^Cardinal; | |
| 86 | + | PQWord = ^QWord; | |
| 87 | + | PBoolean = ^Boolean; | |
| 88 | + | ``` | |
| 89 | + | ||
| 90 | + | См. также: | |
| 91 | + | ||
| 92 | + | - Использование [[Pointers/ru|указателей]] | |
| 93 | + | - <http://www.freepascal.org/docs-html/ref/refse15.html> | |
| 94 | + | ||
| 95 | + | --- | |
| 96 | + | *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](/wiki-contact).* |
