Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ахмадулин Р.К. технологии программирования.doc
Скачиваний:
9
Добавлен:
10.11.2019
Размер:
615.94 Кб
Скачать

Файлы Input и Output

К текстовым файлам относятся и стандартные файлы INPUT и OUTPUT. Рассмотренные ранее операторы ввода-вывода с консоли Readln и Writeln являются частным случаем операторов обмена с текстовыми файлами, когда используются стандартные файлы ввода-вывода INPUT и OUTPUT.

Работа с указанными файлами имеет свои особенности, такие как:

  • имена этих файлов в списках ввода-вывода не указываются;

  • применение процедур Reset, Rewrite и Close к стандартным файлам ввода-вывода запрещено.

Вопросы для самопроверки

1. Что такое текстовые файлы?

2. Как описываются текстовые файлы в языке Паскаль?

3. Какие операции над текстовыми файлами Вы знаете?

4. Какие дополнительные процедуры и функции для работы с текстовыми файлами Вы знаете?

5. Что такое файлы Input и Output?

§21. Ссылки и указатели

Каждая переменная, описанная в разделе var, имеет свое имя и описание. Описание, среди прочего, позволяет компилятору определить, сколько байтов памяти необходимо выделить в памяти для переменной. Имя же позволяет обратиться к зарезервированной под переменную ячейке памяти.

Однако каждая переменная, кроме своего имени, имеет и физический адрес: номер ячейки памяти, в которой хранится значение переменной.

Понятие указателя

Указатель представляет собой переменную целого типа, которая интерпретируется как адрес байта памяти, содержащей некоторый элемент данных. Этим элементом может быть переменная, константа, адрес другой переменной и т.д.

Адрес интерпретируется двумя шестнадцатибитными словами BA:BS, где BAсегментный адрес, BSсмещение. Сегмент – участок памяти длиной 64 Кбайта.

При обращении к переменной по имени программа сама определяет, по какому адресу находится ее значение. Указатель же позволяет хранить адрес произвольной ячейки памяти, в которой могут храниться те или иные данные.

Описание указателей

Существует два типа указателей: типизированные и нетипизированные.

Типизированные указатели хранят адрес данных первого байта какого-либо конкретного типа. Для объявления таких указателей обычно используется символ ^, который размещается непосредственно перед типом данных, на значения которого ссылается типизированный указатель:

Пример:

type

IntPtr = ^Integer;

var

P1 = IntPtr;

P2 = ^Integer;

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

Пример:

type

Link = ^Node; {тип Node будет описан только в следующей строке!}

Node = record

Key: Integer;

Next: Link;

end;

Нетипизированные указатели хранят адрес данных, не связанные с каким-либо конкретным типом данных. Они могут ссылаться и на целочисленные данные, и на символьные, и т.д. В этом случае используется ключевое слово Pointer.

Пример:

var

P: Pointer;

Такая переменная представляет собой адрес байта данных, начиная с которого хранятся какие-либо данные произвольной длины.

Операции с указателями

Определение адреса

Физический адрес любой переменной можно узнать при помощи стандартной функции:

addr(<имя_переменной>): <указатель>

или унарной операции

@<имя_переменной>.

Пример:

var

P: Pointer;

intP: ^integer;

x: integer;

P := addr(x);

P := @x;

intP := addr(x);

intP := @x;

Разыменование

Указатель – это лишь адрес ячейки памяти. Для обращения к содержимому такой ячейки используют операцию, называемую разыменованием. Записывается такая операция следующим образом:

<имя_указателя>^

Отметим, что операция разыменования применима лишь к типизированным указателям.

Пример:

var

intP: ^integer;

x: integer;

intP := @x;

intP^ := 10;

writeln(intP^);

Присваивание

В случае указателей при присваивании получают лишь новый адрес памяти. Содержимое самих ячеек памяти остается неизменным.

Пример:

var

intP1: ^integer;

intP2: ^integer;

x := 3;

intP1 := @x;

y := 4;

intP2 := @y;

intP1 := intP2; {оба указателя ссылаются на значение 4}

intP2^ := 7; {оба указателя ссылаются на значение 7}

В операции присваивания могут фигурировать только указатели, адресующие переменные одинаковых типов данных. Обойти эти ограничения позволяет универсальность нетипизированного указателя Pointer, совместимого с указателями любых типов:

Пример:

var

intP1: ^integer;

intP2: ^integer;

realP: ^real;

P: Pointer;

intP1 := intP2;

{нельзя realP := intP1}

P := intP1;

realP := P;

У указателей также существует свой "ноль", который означает, что указатель не указывает никуда:

p:= nil;

Сравнение

Для указателей определены две операции сравнения: равно (=) и не равно (<>).

Две переменные, описанные как указатели на один и тот же тип данных, считаются совпадающими, если они указывают на одну и ту же область памяти.

Для разнотипных указателей сравнения невозможны. Однако сравнивать типизированный и нетипизированный указатели можно.