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

Указатели - это особый тип данных. В переменных этого типа хранятся адреса других переменных содержащих полезную для программы информацию. На первый взгляд может показаться, что использование указателей приводит к лишним затратам памяти и к усложнению программы, а также существе усложняет и сам процесс программирования. В данной главе мы, приведем такие примеры использования указателей, из которых станет ясно, что все дополнительные затраты на их хранение и обработку окупаются в полной мере. Работа с указателями предусмотрена не только в Pascal, но и в некоторых других языках программирования. Например, в языке С указатели используются практически в любой программе.

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

1.1. Указатели и адреса

Известно, что адресом переменной является адрес первого байта ячейки памяти, которая под нее отводится. Для данных структурных типов (массивов и записей) их адресом считается адрес первого байта первого элемента.

В Turbo Pascal существует возможность прямого доступа к любому байту оперативной памяти по его адресу при помощи определенных в модуле system массивов Mem, MemW и MemL, которые позволяют записать информацию или прочитать ее непосредственно из ячеек памяти (один, два или четыре байта). Это очень опасные действия, поэтому они исключены в 32- разрядных системах программирования. Все же дадим краткие пояснения для тех, кто работает в среде Borland (Turbo) Pascal.

В качестве индекса в этих массивах используется адрес, записанный в виде, принятом в DOS: сегмент : Смещение относительно начала сегмента. Такой странный способ записи адреса связан с тем, что в операционной системе DOS вся память разбита на сегменты, размеры которых не превышают 64 Кбайт. Для получения абсолютного адреса из пары сегмент Смещение система прибавляет к сегменту справа шестнадцатеричный ноль (это четыре нуля в двоичной системе), а затем складывает его со смещением. Таким способом можно адресовать 1 Мбайт памяти.

Например, начальный адрес видеобуфера запишется в виде $B800:$000, а обратиться к самому первому его байту можно так: Mem[$В800:$0000], к первым двум байтам — MemW[$B800:$0000], к первым четырем байтам — MemL [$B800:$0000]. Абсолютный адрес, соответствующий данной паре, — $B8000.

Еще один пример для любознательных — оператор mem[0:$41C]:=mem[0:$41А]; можно применить для принудительной очистки буфера клавиатуры. Здесь адрес маркера конца буфера клавиатуры приравнивается к адресу его начала. Конечно, в данном случае лучше воспользоваться средствами модуля crt.

Имеется еще один способ обращения к оперативной памяти — использование служебного слова absolute при описании переменной. В этом случае переменная будет располагаться именно по тому адресу в оперативной памяти, который указан после absolute. Разумеется, использование служебного слова absolute — столь же опасный способ, как и обращение к памяти через предопределенные массивы.

Однако absolute может использоваться и более безопасным способом, позволяя совмещать в памяти две переменные с разными именами. В языке Pascal есть специальная операция получения указателя на переменную (или процедуру) — она обозначается как @. Имеется также эквивалентная ей функция addr.

Например, @x или addr(х) — адрес переменной х.

Имеется и обратная операция получения значения переменной по ее адресу, которая обозначается знаком ^. Например, р^ переменная с адресом р.

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

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

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

Описание двух видов указателей выполняется по-разному:

var p1: ^integer; {указатель на переменную целого типа}

p2: ^string; {указатель на стоку}

p3 pointer; {нетипизированный указатель}

Заметим что тип pointer совместим со всеми типами указателей. В дальнейшем изложении для удобства имена всех указателей будем начинать с буквы p (pointer).

Каждый указатель размещается в сегменте данных или в стеке (если он объявлен в подпрограмме) и занимает там 4 байта. Это дополнительные “накладные расходы’ памяти. Поэтому обычные переменные очень редко создают и уничтожают динамически, оставляя эту возможность для больших совокупностей данных.

Чем больше размер динамической переменной, тем меньше доля накладных расходов. Например, при хранении в динамической памяти массивов больших размеров лишние 4 байта, затраченные на указатель, несущественны.


Информация о работе «Ссылочные типы. Динамические переменные»
Раздел: Информатика, программирование
Количество знаков с пробелами: 37264
Количество таблиц: 2
Количество изображений: 8

Похожие работы

Скачать
10828
0
0

... ссылочного типа:  <задание ссылочного типа>::= ^<имя типа> ^ - признак ссылочного типа; <имя типа> - имя стандартного либо описанного ранее типа. Это тип динамических объектов, которые может представлять переменная ссылочного типа. Надо подчеркнуть , что здесь может быть только имя типа.  Сами переменные ссылочного типа вводятся обычным образом. type массив = array ...

Скачать
274963
85
0

... ячейка, а имя переменной превращается в адрес ячейки. Появление этого адреса происходит в результате работы специального оператора языка (NEW), однако его значение в большинстве случаев не используется при программировании на алгоритмических языках типа Паскаль. Условимся считать, что адрес ячейки, которая будет хранить переменную А, есть А. Или, другими словами, А - это общее имя переменной и ...

Скачать
94620
8
0

... Закрыть программу можно нажатием на кнопку «Закрыть» или F10. Заключение В квалификационной работе мы попытались раскрыть более полно и наглядно понятие линейного списка, однонаправленного и двунаправленного списков, стека, дека и очереди. Сформировать и закрепить познавательный интерес к данной теме у учащихся. Выявлять и развивать творческие способности в использовании полученного навыка при ...

Скачать
19204
5
5

... "nсреднее целое равно " << MidInt / double(NMax) << "n"; cout << "среднее вещественное равно: " << MidReal / n << "n"; fclose(t); } Списки Обсудим вопрос о том, как в динамической памяти можно создать структуру данных переменного размера. Разберем следующий пример. В процессе физического эксперимента многократно снимаются показания прибора (допустим, термометра) ...

0 комментариев


Наверх