Лекция 7 Указатели. Указатели и их применение — КиберПедия 

Автоматическое растормаживание колес: Тормозные устройства колес предназначены для уменьше­ния длины пробега и улучшения маневрирования ВС при...

Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...

Лекция 7 Указатели. Указатели и их применение

2019-12-21 132
Лекция 7 Указатели. Указатели и их применение 0.00 из 5.00 0 оценок
Заказать работу

 в программировании (2 часа)

План

Понятие динамической памяти

Указатели и их объявление

Понятие динамической памяти

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

  • сама программа пользователя;
  • системные программы времени выполнения, которые осуществляют вспомогательные действия при работе программы пользователя;
  • определяемые пользователем структуры данных и константы;
  • точки возврата для программ;
  • временная память для хранения промежуточных результатов при вычислении выражений;
  • временная память при передаче параметров;
  • буферы ввода-вывода, используемые как временные области памяти, в которых хранятся данные между моментом их реальной физической передачи с внешнего устройства или на него и моментом инициализации в программе операции ввода или вывода;
  • различные системные данные (информация о статусе устройств ввода-вывода и др.).

Из этого перечня видно, что управление памятью касается широкого класса объектов.

До сих пор мы использовали простейший способ распределения памяти - статическое распределение, т. е. распределение памяти при трансляции программы. То есть когда Вы объявляете переменную

Var A: Array[1..100] of integer;

Вы даете указание компилятору выделить память размера, соответствующего заданному типу, т.е. 2*100=200 байт. Если в программе на нужный программный объект мы ссылаемся по имени А[3], то машинный код содержит ссылку на номер ячейки памяти (адрес байта), начиная с которой размещается этот объект.

Адреса задаются двумя 16-тиразрядными словами (тип word) - сегментом и смещением. Каждое из них способно адресовать 216=65536 байт (64 Кбайт). Для адресации пространства размером в 1 Мбайт требуется 20 разрядов. Сегменты адресуют память с точностью до параграфа - фрагмента памяти в 16 байт. Смещение адресует память с точностью до байта, но впределах сегмента. Реальный (абсолютный) адрес складывается из значения сегмента, сдвинутого на 4 разряда влево (умноженного на 16), и смещения. Фрагмент программы вычисления абсолютного адреса в реальном режиме:

Var Segment, Offset: word; Address: LongInt;   Address:= Segment*16+Offset;

Программа на Паскале получает один сегмент данных, поэтому область памяти, в которой могут быть размещены статические переменные Вашей программы, ограничена 64 Кбайтами. При попытке исполнить программу, требующую большего размера памяти, будет выдана ошибка:

Error 49: Data Segment too large{Слишком большой сегмент данных}

При динамическом распределении памяти Вы можете запросить блоки размером до одного сегмента (64 Кбайт) каждый, причем их можно требовать в пределах основной памяти (640 Кбайт) в реальном режиме и без программных ограничений в защищенном.

Бывают такие данные, размер которых выясняется только при выполнении программ. Кроме того, иногда мы не знаем, будет существовать некоторый объект или нет.

Например, в программе для обработки текстов (такие программы называются "текстовыми процессорами") требуется организовать поиск слов, определенных пользователем. Естественно, что определить заранее длину слова, которое будет задано, невозможно. Часто программный объект, причем значительного размера, бывает нужен на непродолжительное время. Использование статических программных объектов в таких случаях очень неэффективно, поскольку программа должна быть рассчитана на максимальные размеры объектов. Область памяти, в которой могут быть размещены статические переменные, ограничена, и, рассчитывая на максимальный размер переменных, мы ограничиваем их количество. В Паскале, кроме статических, предусмотрены динамические объекты. Память под них отводится во время исполнения программы, а когда программный объект можно удалить, память освобождается.

И статические, и динамические переменные вызываются по их адресам. Без адреса не получить доступ к нужной ячейке памяти, но, используя статические переменные, непосредственно адрес

 

Указатели и их объявление

Для работы с динамическими программными объектами в Паскале предусмотрен ссылочный тип или тип указателей. В переменной ссылочного типа хранится ссылка на программный объект (адрес объекта). Указатель состоит из сегмента и смещения. По правилам Паскаля указатели на разные типы данных имеют различные типы, причем эти типы несовместимы, т.е. указатели на разные типы данных не могут ссылаться на один объект.

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

Type A = Array[1..100] of integer; Тип указателя на такой объект: Type tA = ^A;

Переменные ссылочного типа могут определяться как статические, при этом по общим правилам объявления переменных возможна запись с явным и неявным определением ссылочного типа.

Type A = Array[1..100] of integer; {Тип массив из 100 целых чисел} tA = ^A;  {Тип указатель на тип А} Var B: tA;  {Указатель на тип А} C: ^A; {Указатель на тип А}

Для получения данных, соответствующих указателю, символ "^" приводится после имени указателя. Действия с элементами массива типа А могут быть описаны через действия над указателями В и С.

B^[i]:= i; {i-му элементу массива, на который указывает В, присвоить значение i}

C^[i]:= B^[i]; {i-му элементу массива, на который указывает С, присвоить значение i-го элемента массива, на который указывает В}

После выполнения этого кода i-е элементы массивов, на которые указывают В и С, будут равны.

Указатели могут ссылаться на любой тип данных, кроме файлового.

Разберем простой пример, обратив еще раз внимание на синтаксис:

Var P: ^integer;  {Указатель на целое} P^ - переменная целого типа, на которую ссылается Р, она может стоять как в левой, так и в правой части выражений: P^:=16; x:= x+P^;
 

Первый оператор присваивает целочисленной переменной, на которую ссылается Р, значение 16, второй прибавляет к значению переменной х значение 16, второй прибавляет к значению переменной х значение 16. Аналогично определяются и используются указатели на переменные любого типа, в том числе и определенного пользователем.

Обратите внимание, что указатель является обычной статической переменной, а переменная, на которую он указывает - динамической.

Схематически можно представить себе указатель так:

 

Указательная переменная Р может быть в трех состояниях.

1. Содержать адрес какой-либо переменной, память под которую уже выделена.

2. Содержать специальный пустой адрес Nil.

3. Находиться в неопределенном состоянии.

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

Использование имени указателя в программе означает обращение к адресу ячейки памяти, на которую он указывает. Чтобы обратиться к содержимому ячейки, на которую указывает указатель, требуется после его идентификатора поставить символ ^. Эта операция еще называется разыменованием.

Для представления указателя на строку с завершающим нулем в Паскале имеется предопределенный тип PChar. В модуле System этот тип описывается следующим образом:

Type PChar = ^char;

Паскаль поддерживает набор расширенных правил, позволяющих работать со строками с завершающим нулем, используя тип PChar.

Иногда связи между ссылкой и переменной не существует по смыслу задачи, в этом случае с указателем нельзя связать никакой объект, а ссылка должна быть пустой. Зарезервированное слово Nil обозначает константу со значением указателя, который ни на что не указывает. После присвоения

P:= Nil;

указатель не будет указывать ни на какой объект. Значение Nil совместимо с любым ссылочным типом.

Операции "=" и "<>" могут использоваться для сравнения операндов типа указатель. Два указателя равны только в том случае, если они ссылаются на один и тот же объект.


Поделиться с друзьями:

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.053 с.