
- •В языках программирования высокого уровня используется два типа подпрограмм: процедуры и функции
- •Var имя праметра: имя типа
- •10.3.1. Параметры-значения
- •№8. Явная и неявная рекурсия.
- •№9. Множества. Определение. Область применения
- •№10 И 11. Всё о модулях.
- •12 Бтлет
- •64К, зарезервированная в Borland Pascal для данных, может ока-
- •1. Открытые параметры
- •№25. Причины возникновения ооп.
- •№26. Наследование объектов
- •№ 27. Полиморфизм. Свойства.
- •№28.Методы.
- •Identifier" (Ошибка 4; Повторение идентификатора), если попытае-
- •№29. Облости вилимости в модели объектов Pascal
- •№30.Поведение методов объектов при наследовании
- •№31.Инкапсуляция. Свойства.
- •№32. Объекты. Поля и методы.
- •X,y : Word; {Координаты позиции на экране}
- •№33.Определение объекта.
64К, зарезервированная в Borland Pascal для данных, может ока-
заться недостаточной, чтобы содержать все необходимые программе
данные. Указатели позволяют вам обойти эту проблему.
Когда вы описываете в Borland Pascal глобальные переменные,
компилятор выделяет для них память в области, которая называется
сегментом данных. Сегмент данных имеет максимальный размер 64К.
Это означает, что общий объем всех ваших глобальных переменных не
может превышать 64К. Для многих программ этот предел значения не
имеет, но в некоторых случаях вам может потребоваться больший
объем. Ваша программа может выделить в динамически
распределяемой области 80К, поддерживая указатель в виде ссылку
на адрес данных. Указатель занимает в сегменте данных только 4
килобайта. Указатель - это какой-либо адрес в памяти вашего компьютера.
Это может быть адрес переменной, записи данных, либо процедуры
или функции. Обычно вам не важно, где расположен элемент в памя-
ти. Вы можете просто ссылаться на него по имени, и Borland Pascal
знает, где его нужно искать.
Именно это происходит, когда вы описываете переменную. Нап-
ример, если программа включает в себя следующий код, то вы указы-
ваете компилятору на необходимость зарезервировать область в па-
мяти, на которую будете ссылаться по имени SomeNumber.
var SomeNumber: Integer;
Чтобы хранить указатели, вам требуется переменная-указатель,
а для создания переменной-указателя вам необходим ссылочный тип
(или тип "указатель"). Простейшим ссылочным типом является стан-
дартный тип с именем Pointer. Переменная типа Pointer - это общий
(нетипизированный) указатель, то есть, просто адрес. Он не содер-
жит информации о том, на что он указывает.
Таким образом, чтобы использовать тот же пример SomeNumber,
вы можете присвоить его адрес переменной-указателю:
var
SomeNumber: Integer;
SomeAddress: Pointer;
begin
SomeNumber := 17; {присвоить SomeNumber значение}
SomeAddress := @SomeNumber; {присвоить SomeAddress адрес}
SomeAddress := Addr(SomeNumber); {другой способ получения
адреса}
end.
Нетипизированные указатели в Паскале не используются, пос-
кольку они очень ограничены. Они наиболее полезны, когда указыва-
емый элемент будет изменяться, так как нетипизированный указатель
совместим с любым другим указателем. Типизированные указатели
значительно более полезны, и как вы узнаете в следующем разделе,
они более надежны
Обычно вы определяете ссылочные типы, которые указывают на
конкретный вид элемента, например, целое значение или запись дан-
ных. Как вы далее увидите, можно извлечь преимущество из того
факта, что указателю известно, на что он указывает. Чтобы опреде-
лить типизированный указатель, вы можете описать новый тип, опре-
деленный символом каре (^), за которым следуют один или более
идентификаторов. Например, чтобы определить указатель на Integer,
вы можете сделать следующее:
type PIneger = ^Integer;
Теперь вы можете описать переменные типа PInteger. Если вы
не собираетесь часто использовать ссылочный тип, то можете прос-
то описать переменные, как указатели на уже определенный тип.
Например, если вы определили PInteger как ^Integer, то следующие
описания переменной эквивалентны:
var
X: ^Integer:
Y: PInteger;
ПРОЦЕДУРЫ И ФУНКЦИИ
ДЛЯ РАБОТЫ С ДИНАМИЧЕСКОЙ ПАМЯТЬЮ
Вся динамическая память в Турбо Паскале рассматривается как сплошной массив байтов, который называется кучей. Физически куча располагается в старших адресах сразу за областью памяти, которую занимает
тело программы.
Ниже приводится описание как уже рассмотренных процедур и функций, так и некоторых других, которые могут оказаться полезными при обращении к динамической памяти.
Функция ADDR.
Возвращает результат типа POINTER, в котором содержится адрес аргумента. Обращение:
ADDR ( Х )
Здесь
Х -- любой объект программы (имя любой переменной, процедуры, функции).
Возвращаемый адрес совместим с указателем любого типа. Отметим, что аналогичный результат возвращает операция @.
Функция CSEG.
Возвращает значение, хранящееся в регистре CS микропроцессора (в начале работы программы в регистре CS содержится сегмент начала кода программы). Обращение:
CSEG
Результат возвращается в слове типа WORD.
Процедура DISPOSE.
Возвращает в кучу фрагмент динамической памяти, который ранее был зарезервирован за типизированным указателем. Обращение:
DISPOSE(ТР)
Здесь
ТР -- типизированный указатель.
При повторном использовании процедуры применительно к уже освобожденному фрагменту возникает ошибка периода исполнения. При освобождении динамических объектов можно указывать вторым параметром обращения к DISPOSE имя деструктора.
Функция DSEG.
Возвращает значение, хранящееся в регистре DS микропроцессора (в начале работы программы в регистре DS содержится сегмент начала данных программы). Обращение:
DSEG
Результат возвращается в слове типа WORD.
Процедура FREEMEM.
Возвращает в кучу фрагмент динамической памяти, который ранее был зарезервирован за нетипизированным указателем. Обращение:
FREEMEM (Р, SIZE)
Здесь
Р -- нетипизированный указатель;
SIZE -- длина в байтах освобождаемого фрагмента.
При повторном использовании процедуры применительно к уже освобожденному фрагменту возникает ошибка периода исполнения.
Процедура GETMEM.
Резервирует за нетипизированным указателем фрагмент динамической памяти требуемого размера. Обращение:
GETMEM (Р, SIZE)
За одно обращение к процедуре можно зарезервировать не более 65521 байтов динамической памяти. Если нет свободной памяти требуемого размера, возникает ошибка периода исполнения. Если память не фрагментирована, последовательные обращения к процедуре будут резервировать последовательные участки памяти, так что начало следующего будет располагаться сразу за концом предыдущего.
Процедура MARK.
Запоминает текущее значение указателя кучи HEAPPTR. Обращение:
MARK (PTR)
Здесь
PTR -- указатель любого типа, в котором будет возвращено текущее значение HEAPPTR.
Используется совместно с процедурой RELEASE для освобождения части кучи.
Функция MAXAVAIL.
Возвращает размер в байтах наибольшего непрерывного участка кучи. Обращение:
MAXAVAIL
Результат имеет тип LONGINT. За один вызов процедуры NEW или GETMEM нельзя зарезервировать памяти больше, чем значение, возвращаемое этой функцией.
Функция MEMAVAIL.
Возвращает размер в байтах общего свободного пространства кучи. Обращение:
MEMAVAIL
Результат имеет тип LONGINT.
Процедура NEW.
Резервирует фрагмент кучи для размещения переменной. Обращение:
NEW (ТР)
Здесь
ТР -- типизированный указатель.
За одно обращение к процедуре можно зарезервировать не более 65521 байта динамической памяти. Если нет свободной памяти требуемого размера, возникает ошибка периода исполнения. Если память не фрагментирована, последовательные обращения к процедуре будут резервировать последовательные участки памяти, так что начало следующего будет располагаться сразу за концом предыдущего.
Процедура NEW может вызываться как функция. В этом случае параметром обращения к ней является тип переменной, размещаемой в куче, а функция NEW возвращает значение типа указатель. Например:
type
PInt: ^integer;
var
p: PInt;
begin
p := New(PInt);
. . . . .
end.
При размещении в динамической памяти объекта разрешается в качестве второго параметра обращения к NEW указывать имя конструктора.
Функдия OFS.
Возвращает значение типа WORD, содержащее смещение адреса указанного объекта. Вызов:
OFS (Х)
Здесь
Х -- выражение любого типа или имя процедуры.
Функция PTR.
Возвращает значение типа POINTER по заданному сегменту SEG и смещению OFS. Вызов:
PTR (SEG, OFS)
Здесь
SEG -- выражение типа WORD, содержащее сегмент;
OFS -- выражение типа WORD, содержащее смещение.
Значение, возвращаемое функцией, совместимо с указателем любого типа.
Процедура RELEASE.
Освобождает участок кучи. Обращение:
RELEASE (PTR)
Здесь
PTR -- указатель любого типа, в котором предварительно было сохранено процедурой MARK значение указателя кучи.
Освобождается участок кучи от адреса, хранящегося в PTR, до конца кучи. Одновременно уничтожается список всех свободных фрагментов, которые, возможно, были созданы процедурами DISPOSE или FREEMEM.
Функция SEG.
Возвращает значение типа WORD, содержащее сегмент адреса указанного объекта. Вызов:
SEG (Х)
Здесь
Х -- выражение любого типа или имя процедуры.
Функция SIZEOF.
Возвращает длину в байтах внутреннего представления указанного объекта. Вызов:
SIZEOF (Х)
Здесь
Х -- имя переменной, функции или типа.
Например, везде в программе Primer1 вместо константы SIZEOFREAL можно было бы использовать обращение SIZEOF(REAL)..
№19. Открытые массивы. Особенности работы с ними.
ОТКРЫТЫЕ МАССИВЫ В OBJECT PASCAL
Цель работы: познакомить студентов с некоторыми особенностями массивов в
Object Pascal и развить навыки работы со средой Delphi.
Массивы являются примером структурированного типа данных. Массив -
структура сохраняемых в памяти данных, состоящих из последовательности значений,
относящихся к одному типу. В качестве базового может использоваться любой
объявленный тип.
При разработке подпрограмм общего назначения желательна возможность
обрабатывать массивы различной длины. Но Паскаль позволяет указывать параметры,
тип которых - массивы с определенным количеством элементов. Такие параметры
требуют, чтобы у аргументов был такой же тип данных. Это требование ограничивает
полезность подобных подпрограмм.