trains_hr.gif
 


В ПОМОЩЬ СТУДЕНТУ И ШКОЛЬНИКУ

 


Горбачев Л.И. Основы программирования в среде Turbo Pascal.

[НАЗАД]  [ДАЛЕЕ]

УКАЗАТЕЛИ И ДИНАМИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ.

3. Тип данных "указатель".

   Переменная задается тремя параметрами: именем, типом, значением и адресом. Благодаря типу "указатель" появляется возможность использовать в качестве значения переменной адрес другой переменной, так чтобы такая переменная как бы "указывала" на другую.

Например: Переменная типа "указатель"
Имя
Задание типа
Значение
Адрес
Z
"указывает на переменную типа real"
$24A2:$1000
$1000:$2A34

   Значением переменной Z с адресом $1000:$2A34 является адрес переменной типа real (значение которой записывается начиная с адреса $23A2:$1000).

   Тип данных "указатель" вводится следующим образом:
type real_index = ^real;
var head, tail: real_index;
или
var head, tail : ^real;

даже если наименование real_index не используется.

   Переменная типа "указатель" указывает на переменную типа, заданного в описании типа. Переменная связывается с этим типом. В качестве значения такая переменная имеет адрес той переменной, на которую она указывает.

   Переменной, на которую указывает указатель, не обязательно присваивать какое-либо имя. К ней можно обращаться через имя указателя, а потому она называется ссылочной переменной.

Например: Элементарные операции присваивания для переменных типа "указатель".

   Переменная head типа "указатель" имела в качестве значения адрес вещественного числа 3.25, и имя head^, под которым можно было обратиться к этому числу. Точно так же tail указывала на число 2.45.

   Соответственно нужно различать два типа операций присваивания значения: head^ := tail^;

   Ссылочная переменная head^ получает значение tail^, т.е. head и tail указывают теперь на одинаковые объекты 2.45.

   Согласно head := tail переменные-указатели имеют одно и то же значение, то есть указывают на один и тот же объект 2.45 (обратите внимание на различие формулировок "одинаковые объекты" и "один и тот же объект").

   В последней операции присваивания следует иметь в виду, что head и tail должны указывать на объект одного и того же типа.

Пример: Выдать адрес в форме сегмент: смещение, соответственно, в десятичном и шестнадцатеричном виде.
[program PointerTest]

   Оператор присваивания var rptr : ^real;
wptr : ^word;
rptr := wptr;
приводит при компиляции к ошибке, поскольку rptr и wptr - объекты различного типа.

   Между тем в качестве значения интерес представляет только один адрес, а потому существует стандартный тип pointer, совместимый со всеми типами указателей.

   Ответим на следующие три вопроса:

  • Как присваивается значение переменной типа "указатель"?
  • Какие операторы и константы существуют для переменной типа "указатель"?
  • Как можно выдать значение переменной типа "указатель"?
  1. Начнем с первого вопроса: Как присвоить переменной Р типа "указатель" некоторое значение? Для этого существует две принципиально различных возможности:
    • с помощью стандартной процедуры new(P) переменная Р получает адрес динамической памяти и там резервируется место для переменной P^;
    • через оператор присваивания Р := допустимый адрес.

       Рассмотрим сначала второй случай. Существует оператор @ для задания адреса, применимый ко всем переменным:
    var i : integer;
    r : real;
    zi : ^integer;
    zr : ^real;
    i := 135; zi := @i; (* Итак, zi^ = 135 *)
    r := 1.3; zr := @r; (* Итак, zr^ = 1.3 *)

       Кроме того, для работы с адресами существуют функции: addr(x), ptr(seg, ofs), seg(x), ofs(x), dseg, cseg, sseg.

  2. Перейдем ко второму вопросу: Какие константы и операторы существуют для переменных типа "указатель"? Для такого типа переменных имеется единственная константа nil, т.е. после
    var P : pointer;
    P := nil;
    переменная Р не указывает ни на что (внутреннее представление $0000:$0000). На вопрос об операторах ответить просто: их нет, т.е. ничего подобного Р + 2 или Р - sizeof(real) не существует!
  3. Остановимся на третьем вопросе: Как можно выдать значение переменной типа "указатель"?Запись
    var P : pointer;
    P := какой-либо адрес;
    write(P);
    приведет к ошибке "Cannot write variable of this type" ("Нельзя записать переменную такого типа"). Итак, для того, чтобы вывести значение Р в нужной Вам форме в виде абсолютного адреса (отдельно СЕГМЕНТ:СМЕЩЕНИЕ) в десятичном или шестнадцатеричном представлении, нужно написать собственную процедуру.

   Может сложиться представление, что после var P:^integer переменная Р^ является совершенно обычной целой переменной. Это так лишь тогда, когда Р имеет некоторое определенное значение, а именно адрес Р^. Наиболее распространенная ошибка, когда программу начинают строкой: Р^ := 17; не присвоив Р значения, например, с помощью new(P). Тогда не ясно, где же находится константа 17.

Пример: С помощью данной программы осуществляется ввод ряда целых чисел, а затем осуществить вывод в обратном порядке.
Head - голова; Pair - пара;
Tail - хвост; Ref - (reference) - ссылка, упоминание.
[program DemoStack]

[НАЗАД]  [ДАЛЕЕ]


Главная
Новости
TurboPascal
Учебное пособие
Лекции
Исходники
Математика
Книги
Лекции
Шпоры
ЦТ и ЕГЭ
Физика

Книги

Шпоры
ЦТ и ЕГЭ

Литература

Сочинения

Краткие содержания

Другое
Мой родной край
Фотогалерея
Форум
Ссылки

Гостевая






 

                                        © Copyright(c) 2004 Amro Group. All rights reserved

 

Hosted by uCoz