Бестиповые указатели.


Дата добавления: 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;