Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций по КИТ.doc
Скачиваний:
4
Добавлен:
04.11.2018
Размер:
2.3 Mб
Скачать

Рекурсивные процедуры

В VВА возможно создание рекурсивных процедур, т. е. процедур, вызываюх самих себя. Стандартным примером рекурсивной процедуры является процедура вычисления факториала, т. е. функции, возвращающей результат произведения первых n натуральных чисел, где n — аргумент функции. Для этой функции имеется стандартное обозначение: Fact(n)=n!, где Fact (0) = 1. Ясно, что

Fact (n) = n Fact (n - 1)

Основываясь на данном соотношении, приводимая ниже рекурсивная функция вычисляет значение факториала.

Function Fact(n As Integer) As Integer

If n<l Then

Fact = 1

Else

Fact = Fact (n - 1) n End If End Function

Другим стандартным примером применения рекурсивных функций является нахождение наибольшего общего делителя двух целых чисел по алгоритму Евклида. Наибольший общий делитель (НОД) двух целых чисел — это наи­большее целое, на которое делятся оба числа. Например, НОД (10, 14) = 2 и НОД (15, 31) = 1.

Алгоритм Евклида состоит в следующем:

1. Если а делится на b, то НОД(а, b) = b

2. В противном случае — НОД(а, b) = НОД(b, a Mod b)

Приводимая ниже рекурсивная функция программирует алгоритм Евклида.

Function НОД(Целое1 As Long, Целое2 As Long) As Long

If Целое2 Mod Целое1 = О Then

НОД = Целое1

Else

НОД = НОД(Целое2, Целое! Mod Целое2)

End If

End Function

Несмотря на элегантность рекурсивных процедур, применять их надо с ос­торожностью,

т. к. неаккуратное использование может привести к пробле­мам с памятью — многократный вызов такой процедуры быстро исчерпыва­ет стековую память.

Область определения переменной

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

  1. Переменные уровня процедуры используются только в процедуре, в ко­торой они описаны при помощи инструкции Dim, размещенной в проце­дуре.

  2. Переменные уровня модуля используются только в модуле, в котором они описаны при помощи инструкции Dim, размещенной в области опи­сания модуля, т. е. перед описанием процедур.

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

Время жизни переменной

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

Процедуры обработки ошибок и отладка программ Разработка процедур, предотвращающих появление ошибок

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

- Предотвращение ошибок: программно анализировать вводимые или вычисляемые данные и в случае, если они могут приводить к ошибке, обеспечить, чтобы программа информировала пользователя о необходимости корректного задания данных.

- Обработка ошибок: в случае появления ошибки, перехватить ее, обработать и программно откликнуться на возникшую ошибку.

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

В данном разделе рассмотрим процесс создания приложения, в котором предотвращается появление ошибок, на простейшем примере:

- В диалоговом окне два поля (Числитель И Знаменатель) предусмотрены для ввода данных. Пользователь вводит в них по числу (рис. 12.1).

- По нажатию кнопки Счет, программа делит число, введенное в поле Числитель, на число, введенное в поле Знаменатель, и выводит полученный результат в поле Ответ.

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

Private Sub CommandButton1_Click()

Dim Числитель, Знаменатель, Результат As Double

Числитель = CDbl(TextBox1.Text)

Знаменатель = CDbl(TextBox2.Text)

Результат = Числитель / Делитель

TextBox3.Text = CStr(Результат)

End Sub

Несмотря на то что рассматриваемая ситуация очень простая, она уже таит в себе множество подводных камней. Например, если пользователь по невнимательности забудет ввести в поле Числитель или в поле Знаменатель число, при нажатии кнопки Счет происходит аварийное прерывание выполнения программы с малопонятным сообщением о несоответствии типов, отображаемом в диалоговом окне Microsoft Visual Basic (рис. 12.2).

Рис. 12.1. Диалоговое окно Деление

Рис. 12.2. диалоговое окно Microsoft Visual Basic с сообщением об ошибке

Данное сообщение об ошибке связано с одной из следующих двух инструкций в программе:

Числитель = CDbl(TextBox1.Text)

Знаменатель = CDbl(TextBox2.Text)

где аргументом функции CDbl должна быть строка, преобразуемая в число. Если в какое-то из полей, Числитель ИЛИ Знаменатель, ничего не введено, по умолчанию из этого поля будет считываться пустая строка. Но пустая строка не может быть преобразована в число, и поэтому из-за функции CDbl происходит ошибка. Ошибка о несоответствии типов возникнет также, если в одно из полей пользователь по неосторожности введет число с десятичной занятой, а установками системы предусматривается десятичная точка и наоборот.

Такие ошибки ввода легко избежать, если производить в программе предварительную проверку: преобразуются ли вводимые данные в числа? Эту предварительную проверку можно, например, сделать, как показано в следующей процедуре, в которой предусмотрены:

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

Если вводимая информация не преобразуется в числа, то выдается сообщение о поле, в которое некорректно введены данные, и на него перемещается фокус. Например, в ситуации, показанной на рис. 12.3, в поле Знаменатель было введено число с десятичной запятой, в то время как установки системы предусматривают десятичную точку.

Поэтому процедура вызвала отображение диалогового

Рис. 12.3. Пример сообщения о некорректном вводе данных

окна деление с сообщением об ошибке в знаменателе и установила фокус на поле Знаменатель.

Private Sub CommandButton1_Click()

Dim Числитель, Знаменатель, Результат As Single

If IsNumeric(TextBox1.Text) = False Then

MsgBox “Ошибка в числителе”,

vbInformation, “деление”

TextBox1.SetFocus

Exit Sub

End If

If IsNumeric(TextBox2.Text) = False Then

MsgBox “Ошибка в знаменателе”,

vbInformation, “деление”

TextBox2.SetFocus

Exit Sub

End If

Числитель = CDbl(TextBox1.Text)

Знаменатель = CDbl(TextBox2.Text)

Результат = Числитель / Делитель

TextBox3.Text = CStr(Результат)

End Sub

Но это еще не все подводные камни, которые подстерегают неосторожного пользователя при вводе данных даже в этом простом примере. Если пользователь в поле Знаменатель введет 0, то также произойдет аварийная остановка выполнения программы с отображением в диалоговом окне Microsoft Visual Basic сообщения: деление на 0. для избежания подобной ошибки будем проверять не только, являются ли введенные в поле данные числом, но и что это не ноль. Например, добавим перед расчетным блоком в процедуре следующую дополнительную проверку:

If CDbl (TextBox2.Text) = 0 Then

MsgBox “Знаменатель не может быть нулем”,

vbInformation, “деление”

TextBox2.SetFocus

Exit Sub