Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
kitkat_otvety.doc
Скачиваний:
3
Добавлен:
01.08.2019
Размер:
3.29 Mб
Скачать

Билет 12

  1. Указатели и операции над ними.

  2. Основные элементы отладки. Пошаговое выполнение программы. Точки останова. Окно просмотра. Специфика просмотра значения переменных в Delphi.

1) Оперативная память ПК представляет собой совокупность ячеек для хранения информации - байтов, каждый из которых имеет соб­ственный номер. Эти номера называются адресами, они позволяют обращаться к любому байту памяти. Object Pascal предоставляет в распоряжение программиста гибкое средство управления динамиче­ской памятью - так называемые указатели. Указатель - это пере­менная, которая в качестве своего значения содержит адрес байта памяти. С помощью указателей можно размещать в динамической памяти любой из известных в Object Pascal типов данных. Лишь не­которые из них (Byte, char, Shortint, Boolean) занимают во внут­реннем представлении один байт, остальные - несколько смежных. Поэтому на самом деле указатель адресует лишь первый байт дан­ных. Адреса переменных можно хранить в переменных специального типа - указателях. Указа­тели могут быть типизированными и нетипизированными. Типизированный указатель мо­жет хранить адрес переменной определенного типа. Описывается указатель, как и любая другая переменная, в разделе var:

var

< имя указателя >:^< тип >;

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

Указателю может быть присвоено пустое значение nil:

<имя указателя> := nil; означающее, что переменная ни на что не указывает, т.е. не содержит адрес какой-либо ячейки памяти. Как правило, при запуске программы все указатели содержат зна­чение nil. Если переменные являются указателями на один и тот же тип, то им можно присва­ивать значения друг друга: <имя указателя1> := <имя указателя2>; Для того чтобы получить значение, на которое ссылается указатель, надо выполнить операцию разыменования указателя. Для этого надо поместить значок ^ справа от указа­теля. Например, если L - переменная типа integer, то допустимы следующие операторы:

pol := L; // в pol помещен адрес L

L := pol^ + 6; // эквивалентно L := L+6;

Адрес любой переменной можно получить с помощью операции взятия адреса @. Например, приведенные выше операторы можно было бы заменить эквивалентными

pol := @L;

L := pol^+6;

Память под любую динамически размещаемую переменную вы­деляется процедурой New. Параметром процедуры является типизированный указатель:New(<Имя указателя>);

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

Процедура Dispose выполняет обратную операцию - освобождает память, динами­чески выделенную процедурой New. Параметром процедуры Dispose является указатель, в котором хранится адрес области памяти, выделенный ранее процедурой New, Dispose(<Имя указателя>); В результате выполнения процедуры Dispose освобождается участок динамической памяти, но не меняется значение указателя. Освободившемуся указателю можно присво­ить значение nil, если планируется его дальнейшее использование. Нетипизированный указатель не связан с каким-либо конкретным типом данных. Для описания нетипизированного указателя служит зарезервированное слово Pointer:var <Имя указателя>:Pointer;

Нетипизированныс указатели используют в тех случаях, когда в процессе работы про­граммы тип и структура данных изменяются. Для работы с нетипизированными указате­лями следует использовать следующие процедуры:

procedure GetMem(var P: Pointer; Size: Integer); Резервирует за нетипизированным указателем Р фрагмент динамической памяти тре­буемого размера Size.

procedure FreeMem(var P: Pointer[; Size: Integer]);Возвращает в динамическую память фрагмент, который ранее был зарезервирован за нетипизированным указателем Р.

function SizeOf(X): Integer;Возвращает количество байтов, занимаемых переменной или типом X.

Нетипизированные указатели совместимы с любыми типизированными указателями.

При работе с динамической памятью следует учитывать следующее:

Если динамическая память была выделена при помощи процедуры New, то освобож­дение памяти осуществляется только при помощи процедуры Dispose. Это же правило распространяется на процедуры GetMem и FreeMem. Начальный адрес и объем динамической памяти, освобождаемой при помощи проце­дуры FreeMem, должны быть точно такими же, как и при выделении динамической па­мяти при помощи процедуры GetMem. Указатели и динамическая память используются в Delphi весьма интенсивно. Так, например, параметры-переменные в подпрограммах это не что иное, как указатели. Ука­зателем является переменная динамического массива, указывающая на начало массива. Кроме того, в языке Object Pascal имеется ряд предопределенных типов указателей, например, так называемая нультерминальная строка типа PChar. С типом PChar совмес­тим массив символов с нулевой нижней границей, имеющий нулевой символ (#0) в конце. Отличием между символьным массивом и переменной типа PChar является то, что место для массива в памяти выделяется статически, т.е. на этапе компиляции, а для нуль-терминальной строки место в памяти выделяется во время работы программы, т.е. ди­намически.

Тип PChar используется в Delphi для совместимости с аналогичными типами, имею­щимися в других системах программирования и операционной системе Windows, а так­же при вызове стандартных подпрограмм, имеющих формальные параметры этого типа.

2) Термин «отладка» означает исправление ошибок в программе и обеспечение ее пра­вильной работы. Возникающие в процессе создания программы ошибки классифициру­ются следующим образом:

1. Синтаксические ошибки.

2. Ошибки периода выполнения программы.

3. Логические ошибки.

Delphi позволяет легко найти и исправить ошибки, возникающие как во время ком­пиляции (синтаксические ошибки), так и во время выполнения. В состав интегрирован­ной среды разработчика Delphi входит мощный и гибкий отладчик, который позволяет построчно выполнять программу, анализируя при этом выражения и модифицируя значения переменных. Этот отладчик встроен в интегрированную среду разработчика Delphi, благодаря чему можно редактировать, компилировать и отлаживать програм­му, не выходя из Delphi. Пошаговое выполнение программы. Такое выполнение про­граммы называется трассировкой программы. В Delphi имеется два режима трассировки - без захода в процедуру и с заходом в процедуру. Трассировка без захода в процедуру осуществляется по команде Run | Step Over либо при нажатии на функциональную клавишу F8. При этом трассировка подпрог­рамм не осуществляется, а при появлении в тексте программы обращений к процедурам либо функциям соответствующие подпрограммы выполняются как один оператор. Трассировка с заходом в процедуру выполняется по команде Run | Trace into либо при нажатии на функциональную клавишу F7. В этом случае пошагово будет выполняться не только основная программа, но и все подпрограммы. Кроме этого, при отладке программы можно использовать так называемые точки останова программы (breakpoint). Точками останова программы называются некото­рые, специальным образом помеченные строки программы. При достижении точки ос­танова программа приостанавливает свою работу. В этот момент программист может просмотреть значения наблюдаемых переменных или начать трассировку программы. Установить или снять точку останова - для этого достаточно щелкнуть левой кнопкой мыши по служебной зоне слева от выбранной стро­ки либо установить текстовый курсор в нужной строке и нажать функциональную клави­шу F5. Для того чтобы в процессе пошагового выполнения наблюдать за изменением значении перемен­ных, имеющихся в программе, необходимо раскрыть окно наблюдения Watch List и внести в него имена наблюдаемых переменных или выражений. Для откры­тия окна Watch List необходимо выполнить команду View | Debug Windows | Watches. Для добавления нового выражения или переменной необходимо щелкнуть по окну Watch List правой кнопкой мыши и в появившемся контекстном меню выбрать пункт Add Watch... . В результате появится окно Watch Properties. Поле Expression окна Watch Properties .предназначено для ввода имен наблюдаемых переменных или выражений. Поле Repeat count используется в случае наблюдения мас­сивов и определяет количество показываемых элементов массива. Поле Digits служит для задания количества значащих цифр при отображении вещественных значений. Вык­лючатель Enabled разрешает либо запрещает выводить в окно наблюдения значение со­ответствующей переменной или выражения. Выключатель Allow Function Calls разрешает либо запрещает помещать в окно наблюдения выражения, содержащие вызовы функций. Содержащиеся в нижней части окна переключатели предназначены для определения вида представления значений различных типов. При выполнении трассировки программы, кроме наблюдения значений переменных программы, можно одновременно и изменять эти значения. Это делается при помощи окна Evaluate/Modify, которое вызывается командой Run | Evaluate/Modify..; либо при помощи комбинации клавиш Ctrl+F7. Если в процессе выполнения трассировки открыть окно Evaluate/Modify, ввести в поле Expression имя переменной или выражения и нажать на кнопку Evaluate, то в полях Result и New value отобразится соответствующее текущее значение.

Если в поле Expression введено имя переменной, то ее значение можно изменить в поле New value и нажать кнопку Modify. После этого в программе будет использовать­ся новое значение переменной. Кнопка Watch предназначена для переноса выражения или переменной из окна Evaluate/Modify в окно наблюдения Watch List.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]