Данные системы Turbo Pascal
Классы памяти:
1. Статический - постоянно присутствуют в памяти от начала до конца работы программы(типизированные константы; константы и переменные основной части программы).
Особый интерес в связи с этим представляют собой типизированные
константы. Дело в том, что даже если эта константа объявлена в
подпрограмме, то для нее выделяется статический класс памяти.
Пример:
procedure <имя процедуры>;
const
x:integer = 20; { x - типизированная константа}
begin
<делаем что-нибудь>
x:=30;
end;
При первом вызове этой процедуры переменной X присвоится значение 20, но при повторном ее вызове X будет равно уже 30, т.к. повторной инициализации переменной X не происходит (статический класс памяти).
2. Автоматический - память объектам выделяется при входе в блок и освобождается при выходе из него (локальные переменные подпрограмм)
3. Управляемая память(динамическая) - пользователь сам решает когда и сколько памяти ему нужно. Для реализации динамической памяти используются переменные типа указатель. Работа с динамической памятью реализуется через так называемую кучу, которая состоит из всей свободной памяти на данном компьютере. Когда пользователю необходимо выделить память он посылает администратору кучи запрос на выделение необходимого количества памяти с помощью функций GetMem или New. Если такое количество есть, то указателю присваивается адрес начала свободной области памяти необходимого объема. А потом пользователь интерпретирует полученную память так как хочет. В конце работы пользователь обязан вернуть то количество памяти которое он взял.
Примечание:
Наглядный пример - блокнот из 11 страниц в котором пишут карандашом. Естественно, что в любой момент любую страницу можно очистить стирательной резинкой. Давайте поработаем администратором кучи. Для начала зарезервируем одну страницу для рабочих нужд (на ней мы будем хранить указатели). Указатель - это ссылка на место в блокноте где мы храним связанные с ними (указателями) данные. Прежде чем работать с какой-либо из страниц блокнота мы на нашей страничке записываем данные о начальной страничке наших данных, а также количество взятых страниц. Т.е. например для пункта 2 (см. текст ниже)
мы пишем например так:
Работа1 - 1 страница - 3 страницы
Записи такого вида позволяют не запутаться компилятору в сложной структуре памяти.
1) Блокнот в начале работы пустой:
0 0 0 0 0 0 0 0 0 0
это означает что все 10 страниц - пустые (0 - ничего нет)
2) Предположим, что нам понадобилось для 1 работы 3 страницы. Ищем первые три пустые
страницы и забираем их (это в переводе на компьютерный язык называется выделением
памяти):
1 1 1 0 0 0 0 0 0 0
3) Для следущей 2 и 3 работы понадобилось соответственно 1 и 4
страницы. Получим:
1 1 1 2 3 3 3 3 0 0
4) Теперь предположим, что 2 работу мы сделали и страницы, выделенные
под эту работу нам не нужны, - стираем все что на них написано и
они снова готовы к использованию(освобождение памяти):
1 1 1 0 3 3 3 3 0 0
5) Теперь освободим страницы для работы 1 и выделим для 4 работы 2
страницы
0 0 0 0 3 3 3 3 0 0
4 4 0 0 3 3 3 3 0 0
6) Как вы видите страницы оказались фрагментированными: сначала идут 2
занятые страницы, потом 2 пустые, потом 4 занятые и 2 пустые
страницы, т.е. свободно 4 страницы.
Предположим, что теперь вам необходимо 3 страницы для следующей
работы. Казалось бы, чего проще - ведь четыре пустых страницы, но на
самом деле вы не сможете выделить страницы, т.к. не сможете найти 3
подряд идущих страницы. Обидно, но так же обстоит дело и на
компьютере: из-за фрагментации кучи может возникнуть ситуация когда
свободно больше памяти чем надо, а выделить необходимый объем вам не
удастся и в таких случаях фиксируется ошибка.
4. Базированный класс- память объектам выделяется в одних и тех же участках памяти.
Пример:
var
x:longint;
b:array[1..4] of byte absolute x;
В данном примере память для объекта b, который является массивом из 4 байт, выделяется в том же самом месте, что и для переменной X. Меняя значения массива мы тем самым меняем значение X.
Пример с указателями:
type
ab = array[1..4] of byte; {вводим новый тип}
var
x:longint;
pb:^ab; {pb - указатель на массив из 4 элементов}
begin
<делаем что-нибудь>
pb:=@x; {pb указывает на адрес переменной X}
Примечание:операция @ - взятие адреса объекта
Типы данных:
Логические:
boolean - 1 байт (нормализованный)
ByteBool ¦
WordBool ¦} ненормализованные
LongBool ¦ 0 - false, иначе - true
Целые беззнаковые:
Byte - 1 байт. Значения: 0..255
Word - 2 байта. Значения: 0..65535
Целые знаковые:
ShortInt - 1 байт. Значения: -128..127
Integer - 2 байта. Значения: -32768..32767
LongInt - 4 байта. Значения: -2147483648..2147483647
Вещественные типы данных:
Представляют собой вещественные значения, которые используются в
арифметических выражениях и занимают в памяти от 4 до 10 байт.
Эффективное использование типов single, double, extended, comp возможно только при наличии сопроцессора 8087 при включенной директиве {$N+}. По умолчанию она находится в выключенном состоянии {$N-}. Вещественные десятичные числа в форме с плавающей точкой в таблице представлены в экспоненциальном(научном) виде: mE+p, где m - мантисса (целое или дробное число с десятичной точкой), "E" означает "десять в степени", p - порядок (целое число).
5.18e+02 = 5.18 * 10^2 = 518
10e-03 = 10 * 10^-3 = 0.01
Пример:
var
Summa : Single;
Root1, Root2: Double;
Символьные:
Char - 1 байт (код ASCII - кодовая таблица IBM PC)
В программе значения переменных и констант типа char должны быть заключены в апострофы. Например, 'А' обозначает букву А, ' ' - пробел, ';' - точку с запятой.
Строки символов:
В Turbo Pascal для строк существует такая структура данных как string.
Описывается она по-разному:
string - 256 байт (строка из не более чем 255 символов)
string[max] - max+1 байт (строка из не более чем max символов, где
0<max<256)
Как легко видеть размер строки на 1 байт больше, чем количество доступных символов.
Пример:
var
Name : string[30]; {Строка не более чем из 30 символов}
Address: string; {Строка не более чем из 255 символов}