Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Стек вызовов





Диалоговое <$I[]окно Call Stack > окно Call Stack предназначено для просмотра стека вызовов активных процедур. Активными являются процедуры, выполнение которых было начато, но не завершено. Если ваш код состоит из нескольких вызывающих одна другую процедур (такие процедуры называются вложенными) и вероятная ошибка заключается в логике вызовов процедур, то вам следует воспользоваться диалоговым окном Call Stack, чтобы проследить последовательность вызовов процедур.

Окно Call Stack можно вызвать опцией Call Stack меню View или копкой Call Stack панели Debug. Поскольку это средство является стеком (принцип: последним пришел — первым ушел), вызов первой процедуры находится в самой нижней части стека, а все другие добавляются сверху (рис. 12.16).

Рис. 12.16

Окно Call Stack позволяет проследить последовательность вложенных вызовов процедур.

Для каждой процедуры в окне указывается модуль или имя формы и имя самой процедуры. Кнопка Show в окне Call Stack (при выбранной процедуре) позволяет увидеть (в окне Code) оператор этой процедуры (рис. 12.17), который передает управление следующей процедуре в списке (верхней, согласно стеку).

Рис. 12.17

Окно Code c указанием оператора, который вызывает следующую (в стеке) процедуру.

Наиболее полезным окно оказывается при отладке рекурсивных вызовов. Предположим, вам необходимо в качестве части некоторого задания написать код вычисления факториала, т.е. N!, где N -целое число. Как известно, это делается по формуле N!=N*(n-1)*(N-2) *...*2*1.

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

Листинг 12.1. Функция вычисления факториала

1: Function Factorial(n As Long)

2: 'рекурсивная функция вычисления факториала

3:

4: If n = 0 Then 'условие прекращения рекурсии

5: Factorial = 1

6: Else

7: Factorial = n * Factorial(n - 1)

8: End If

9: End Function

В листинге 12.1 пока нет ошибки. При вызове функции Factorial сначала проверяется, не равен ли параметр n нулю (строка 4). Если — да, вычисления прекращаются, функция возвращает число 1 (строка 5). Например, при n=0 возвращается единица.

Если n=1, то при первом (внешнем) входе после проверки условия в строке 4 управление передается в строку 7 и функция вызывает сама себя с параметром n-1, т.е., 0. При вычислении факториала от 0 возвращается значение 1. Это значение в строке 7 умножается на n, равное 1. Возвращается значение 1.

Если n=2, то при первом (внешнем) входе после проверки условия в строке 4 управление передается в строку 7 и функция вызывает сама себя с параметром n-1, т.е., 1. При вычислении факториала от 1 возвращается значение 1 (конечно, все происходит, как описано в предыдущем случае). Это значение в строке 7 умножается на n, равное 2. Возвращается значение 2.

Если n=3, то при первом (внешнем) входе после проверки условия в строке 4 управление передается в строку 7 и функция вызывает сама себя с параметром n-1, т.е., 2. При вычислении факториала от 2 возвращается значение 2 (снова все происходит, как описано в предыдущем случае). Это значение в строке 7 умножается на n, равное 3. Возвращается значение 12. Можно описывать этот процесс и дальше.

Чтобы проверить работу функции Factorial, создадим небольшое приложение. Форма пусть имеет вид, представленный на рис. 12.18.

Рис. 12.18

Форма приложения для отладки функции Factorial.

Элементы управления этого приложения имеют только свойства, связанные с их отображением на экране. Поэтому нет необходимости приводить эти свойства. Текст модуля формы приведен на рис. 12.19 в окне Code. Код модуля состоит из двух событийных процедур для двух кнопок. Процедура Command1_Click (кнопка с заголовком Вычислить факториал) вызывает функцию Factorial (посредством встроенной функции MsgBox), а процедура Command2_Click (кнопка с заголовком Отмена) выгружает форму, завершая работу приложения.

Если вы создадите подобное приложение и запустите командой Start меню Run, то, введя в текстовом окне некоторое целое число, получите значение его факториала.

 

Рис. 12.19

Код модуля приложения для отладки функции Factorial

А теперь вернемся к окну Call Stack. С помощью созданного приложения легко продемонстрировать, что произойдет в случае наличия ошибки в рекурсивной процедуре и какая информация будет отображаться в окне Call Stack. Пусть, например, вы неправильно задали в функции Factorial (а это бывает чаще всего) условие прекращения рекурсии. А именно, в строке 4 листинга 12.1 вместо n=0 записано n=10. Тогда, если вы введете число меньшее, чем 10, условие прекращения рекурсии никогда не выполнится. Приложение остановится с сообщением об ошибке переполнения стека (рис. 12.20).

Рис. 12.20

Обычно ошибки в рекурсивных процедурах приводят к подобным сообщениям.

Первым действием разработчика приложения после получения сообщения, приведенного на рис. 12.20., должна быть попытка посмотреть окно Call Stack. Конечно, вы скажете, что совершенно понятно, какая информация там сейчас должна быть (рис. 21). Но сейчас это действительно понятно, потому что мы сознательно испортили рекурсивную функцию для демонстрации переполнения стека. На практике вы можете иметь очень много вложенных вызовов, и при получении сообщения о переполнении стека достаточно просмотреть окно Call Stack, чтобы понять, где начинается бесконтрольное заполнение стека.

Рис. 12.21

Стек вызовов переполнен из-за неверного условия прекращения рекурсии

Date: 2015-08-22; view: 409; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию