Бестиповые указатели.
Дата добавления: 2014-01-11; просмотров: 7; лекция была полезна: 0 студентам(у); не полезна: 0 студентам(у).
Опубликованный материал нарушает авторские права? сообщите нам...
Совместимость и преобразование ссылочных типов.
Установка размеров динамической памяти.
По умолчанию для кучи отводится объем оперативной памяти в 655360 байт. Однако в ряде случаев такой объем избыточен или даже не допустим. Например, Pascal-программа, занимающая оперативную память, не в состоянии осуществить вызов какой-либо другой программы, размещенной в отдельном EXE-файле.
Для управления размерами динамической памяти в языке Turbo Pascal служит директива компилятора $M. Эта директива должна располагаться в начале текста программы и иметь три целочисленных параметра, которые разделяются запятыми:
первый - определяет максимальный размер памяти, выделяемый под стек локальных переменных, а два других - задают минимальный и максимальный размеры динамической памяти.
{ $M 10000, 0, 200000 }
Задание минимального размера носит ограничительный характер и устанавливает тот объем требуемой памяти, при отсутствии которого программа вообще не может выполняться. Если параметр 0, то программа запускается в любом случае.
Третий параметр задает максимальный размер требуемой динамической памяти и носит рекомендательный характер. Размер динамической памяти определяется перед началом работы программы исходя из реального наличия свободной оперативной памяти.
Если при запуске программы в оперативной памяти находятся какие-либо программы (например, резидентная часть NC или запуск производится из интегрированной среды ТР), то реальный объем динамической памяти может быть меньше заказанного.
По умолчанию определяется директива {$M 16384, 0, 655360}
Кроме директивы $M в тексте программы можно установить обсуждаемые размеры посредством альтернативы Options/Compiler/Memory Sizes в интегрированной среде.
Все ссылочные типы считаются различными
Type
Tip1 = ^integer;
Tip2 = ^real;
Физическая природа ссылочных типов во всех случаях подразумевает адреса в оперативной памяти, но различные типы определяют несовпадающие множества значений.
Например: переменные
Var
P1 : Tip1;
P2 : Tip2;
не могут передавать друг другу значения. Для ссылочных переменных одного типа это допустимо.
Var
P1, P2 : Tip1;
Begin
P1 := P2;
End.
Тurbo Рascal содержит стандартный ссылочный тип, который позволяет не конкретизировать свой базовый тип, т.е. тип указываемых значений. Этот тип обозначается pointer и совместим со всеми ссылочными типами.
Например:
Var
P1 : ^integer;
P2 : ^real;
P3 : pointer;
допускается присваивание вида:
P3 := P1; P3 := P2; (P1 := P2 нельзя)
Значения типа pointer называются нетипизированным указателями. Реальная работа с такими указателями подразумевает их преобразование в типизированные указатели.
Тurbo Рascal содержит две процедуры распределения памяти, которые выделяют и освобождают области динамической памяти без учета типа тех значений, которые будут в них размещаться. Эти процедуры вызываются с двумя параметрами: указатель типа pointer и размер выделяемой или освобождаемой памяти в байтах.
Например, обращение GetMem(P,20) приведет к выделению области динамической памяти из 20-ти байтов. Максимальный размер, выделяемый GetMem 65521 байт.
Вызов процедуры FreeMem(P,20)освободит занятую область.
В Тurbo Рascal имеются стандартные функции, ориентированные на работу с нетипизированными указателями.
Функции Seg(x) : word и Ofs(x) : word позволяют определить компоненты адреса любого значения. Эти функции имеют один параметр любого типа и возвращают соответствующие значения сегмента и смещения для переменной, переданной в параметре.
Функция Ptr(Seg,Ofs : word) : pointer осуществляет обратное действие, позволяя сконструировать указатель на произвольное место в памяти.
Решение экономного использования памяти состоит в том, чтобы отказаться от структуры ряда записей. Лучше, предварительно определив тип записи, создавать новый экземпляр записи тогда, когда возникает потребность.
Например, необходимо создать список записей, содержащие сведения о сотрудниках учреждения.
Type
Workerrec = record
Name : string [20];
Number : integer;
Salary : real;
end;
Workerptr = ^Workerrec;
Var
Worker : array[1..100] of Workerptr;
Всякий раз, когда требуется принять на работу очередного сотрудника достаточно обратиться к процедуре New с соответствующим указателем. Например:
New( worker[51] );
Запись 51-го служащего создана, теперь можно ссылаться на любое поле.
Например:
Worker [51]^. name;