- •Тема: «Разработка приложений с использованием процедур и функций пользователя»
- •1. Программные модули. Процедуры и функции
- •1.1. Программные модули
- •1.2. Процедуры
- •1.3. Функции
- •1.4. Передача параметров по ссылке и по значению
- •2. Упражнения
- •3. Задания для самостоятельного выполнения
- •1. Используя процедуры общего назначения, составить программы для решения задач с заданным вариантом условия:
- •2. Используя функции, составить программы для решения следующих задач:
1.4. Передача параметров по ссылке и по значению
При вызове процедуры вы передаете в нее некоторые параметры. Внутри процедуры этим параметрам могут быть присвоены какие-то значения, которые сохранятся в них после выхода из процедуры. Таким образом, по умолчанию при передаче переменных в качестве параметров, в процедуру передаются физические адреса переменных. Поэтому внутри процедуры может быть модифицировано их содержимое. Для явного указания передачи параметров по ссылке в процедуру предназначено ключевое слово ByRef. Другим способом передачи параметров в процедуру является передача их по значению. При этом способе передачи параметра в процедуру попадает не сама переменная, а ее значение. Передача параметра по значению задается ключевым словом ByVal. В следующем примере показано отличие передачи параметра по ссылке от передачи параметра по значению.
Пример. Передача параметров по ссылке и по значению.
Private Sub Example(ByVal a As Integer, b As Integer, ByRef c As Integer)
' a передается по значению
' по умолчанию b передается по ссылке
' c передается по ссылке
a = a + 1
b = b + a
c = c + a
End Sub
Private Sub Command1_Click()
Dim a As Integer, b As Integer, c As Integer
a = 1: b = 10: c = 100
Call Example(a, b, c)
Print a ' Отобразится 1
Print b ' Отобразится 12
Print c ' Отобразится 102
End Sub
Пример. Осуществить перестановку
значений переменных a, b,
c в порядке возрастания,
т.е. чтобы
.
Private Sub Swap(ByRef x As Single, ByRef y As Single)
Dim t As Single
t = x
x = y
y = t
End Sub
Private Sub Command1_Click()
Dim A As Single, B As Single, C As Single
A = InputBox("Введите A=") ' Например, А = 4, B = 2, C = 3
B = InputBox("Введите B=")
C = InputBox("Введите C=")
If A > B Then Call Swap(A, B) ' Процедура выполнится; А = 2, B = 4
If B > C Then Call Swap(B, C) ' Процедура выполнится; B = 3, C = 4
If A > B Then Call Swap(A, B) ' Процедура не выполнится
Print "A="; A, "B="; B, "C="; C
End Sub
2. Упражнения
Упражнение 1. Разработаем программу для вычисления площади трапеции по известным значениям длин ее оснований и высоты.
Реализация проекта
1. План решения
Н
а
рисунке показан предлагаемый дизайн
формы:
Рис. 8.1
Назначение каждого элемента управления:
текстовые поля – для ввода значений исходных параметров;
надписи – одна для показа вычисленной площади, остальные – для описания исходных параметров;
линии – для изображения трапеций и исходных линий;
кнопка – для завершения программы по щелчку.
Каждое текстовое поле будет иметь одинаковые процедуры, реагирующие на событие «Нажатие клавиши Enter».
Процедура для кнопки будет аналогична разработанным во всех предыдущих проектах.
2. Создание интерфейса
Используя элемент управления Line (Линия), начертите трапецию (вы вынуждены будете чертить каждую из четырех сторон отдельно). Добавьте линии для указания размеров. У линии есть свойство BorderWidth (ширина), которое позволяет чертить одни линии (например, размерные) тоньше, чем другие.
Поместите на форму пять надписей, три текстовых поля и одну кнопку. Измените размеры и позицию надписей и текстовых полей, как показано на рисунке.
3. Установка свойств
Класс объектов |
Обозначение объекта по умолчанию |
Свойство |
Значение
|
Form |
Form1 |
Caption |
Площадь трапеции |
Label |
Label1 |
Caption |
Сторона a |
Label2 |
Caption |
Сторона b |
|
Label3 |
Caption |
Высота |
|
Label4 |
Caption |
Площадь |
|
Label5 |
Name |
LblS |
|
BorderStyle |
1 – Fixed Single |
||
Caption |
0 |
||
TextBox |
Text1 |
Name |
TxtA |
Text |
0 |
||
Text2 |
Name |
TxtB |
|
Text |
0 |
||
Text3 |
Name |
TxtH |
|
Text |
0 |
||
CommandButton |
Command1 |
Name |
CmdExit |
Caption |
Выход |
4. Написание кода
Событие по умолчанию для текстового поля – это Change (Изменение). А код, который будет написан для текстовых полей, будет реагировать на событие KeyPress (Нажатие на клавишу).
Когда нажата клавиша Enter в любом из текстовых полей, код должен обеспечивать вычисление площади и присваивание вычисленного значения свойству Caption надписи LblS (для этого случая выбрана надпись, а не текстовое поле, так как указанное только что свойство надписи может быть изменено только с помощью кода).
Введите следующий код для текстового окна TxtA:
Private Sub TxtA_KeyPress(KeyAscii As Integer)
'Если нажата клавиша Enter,
If KeyAscii = 13 Then
'то вычисляется площадь
LblS.Caption = (Val(TxtA.Text) + Val(TxtB.Text)) * Val(TxtH.Text)/2
End If
End Sub
Создайте аналогичный код для двух других текстовых полей (отличие будет состоять лишь в заголовках процедур).
В заголовке процедур обработки события KeyPress (Нажатие на клавишу) можно увидеть параметр KeyAscii. Он объявляется как величина целого типа – Integer. Каждое нажатие на клавишу клавиатуры ассоциируется с числовым кодом (так называемым “ASCII-кодом”). Клавиша Enter имеет код 13. Всякий раз, когда нажимается клавиша на клавиатуре, процедура обработки события KeyPress соответствующего текстового поля проверяет, не нажата ли клавиша Enter. Как только это происходит – вычисляется площадь.
Введите следующий код для кнопки:
Private Sub СmdExit_Click()
End
End Sub
5. Сохранение проекта
Сохраните форму и проект под именами трапеция.frm и трапеция.vbp.
6. Тестирование приложения
Запустите программу.
Обратите внимание, что площадь вычисляется только тогда, когда вы нажимаете клавишу Enter.
7. Модификация кода
Код, реагирующий на событие KeyPress (Нажатие на клавишу), одинаков для всех трех текстовых полей. В таких случаях удобно создать процедуру общего назначения, которой могут совместно пользоваться три событийные процедуры. Выберите пункт Add Procedure (Добавить процедуру) из меню Tools:
Рис. 8.2
Введите в поле Name имя процедуры STrap, установите переключатель в положение Private и нажмите клавишу “OK”. Потом введите код общей процедуры:
Private Sub STrap(Key As Integer)
If Key = 13 Then
LblS.Caption = (Val(TxtA.Text) + Val(TxtB.Text)) * Val(TxtH.Text)/2
End If
End Sub
Теперь коды событийных процедур для текстовых полей становятся проще:
Private Sub TxtA_KeyPress(KeyAscii As Integer)
'вызываем общую процедуру STrap
Call STrap(KeyAscii)
End Sub
Private Sub TxtB_KeyPress(KeyAscii As Integer)
Call STrap(KeyAscii)
End Sub
Private Sub TxtH_KeyPress(KeyAscii As Integer)
Call STrap(KeyAscii)
End Sub
Оцените преимущества использования общей процедуры.
Сохраните проект и протестируйте приложение.
Замечание. При вводе данных в текстовое поле могла бы произойти ошибка (при вводе нечисловых значений). Функция Val частично обеспечивает защиту – любые нечисловые данные преобразуются этой функцией в ноль. Улучшенный способ для подтверждения ввода числовых данных – использование функции IsNumeric. Эта функция возвращает значение True или False в зависимости от того, является ли ее аргумент числом или нет. Например, IsNumeric (TxtA.Text) будет иметь значение True, если введено числовое значение свойства Text текстового окна TxtA. Посмотрите, как эта функция могла бы быть использована в гораздо более строгой процедуре STrap:
Private Sub STrap(Key As Integer)
If Key = 13 Then
If IsNumeric (TxtA.Text) And IsNumeric (TxtB.Text) And _
IsNumeric (TxtH.Text) Then
LblS.Caption = (Val(TxtA.Text) + Val(TxtB.Text)) * Val(TxtH.Text)/2
Else
LblS.Caption = ”Ошибка ввода”
End If
End If
End Sub
Упражнение 2. Разработаем программу для вычисления наибольшего общего делителя двух натуральных чисел.
Реализация проекта
1. План решения
Н
а
рисунке показан предлагаемый дизайн
формы:
Рис. 8.3
Назначение каждого элемента управления:
текстовые поля – для ввода значений и вывода результата;
надписи – для описания исходных параметров;
кнопка – для завершения программы по щелчку.
Первые два текстовых поля будут иметь одинаковые процедуры, реагирующие на событие «Нажатие клавиши Enter».
Процедура для кнопки будет аналогична разработанным во всех предыдущих проектах.
2. Создание интерфейса
Поместите на форму две надписи, три текстовых поля и одну кнопку. Измените размеры и позицию надписей и текстовых полей, как показано на рисунке.
3. Установка свойств
Класс объектов |
Обозначение объекта по умолчанию |
Свойство |
Значение
|
Form |
Form1 |
Caption |
НОД двух чисел |
Label |
Label1 |
Caption |
Числа |
Label2 |
Caption |
Наибольший общий делитель |
|
TextBox |
Text1 |
Name |
TxtChislo1 |
Text |
1 |
||
Text2 |
Name |
TxtChislo2 |
|
Text |
1 |
||
Text3 |
Name |
TxtNOD |
|
Text |
1 |
||
CommandButton |
Command1 |
Name |
CmdExit |
Caption |
Выход |
4. Написание кода
Код, реагирующий на событие KeyPress, будет одинаковым для первых двух текстовых полей. Когда нажата клавиша Enter в любом из этих полей, код должен обеспечивать вычисление наибольшего общего делителя и присваивание вычисленного значения свойству Text текстового окна TxtNOD.
Д
ля
вычисления наибольшего общего делителя
двух чисел создадим функцию. Выберите
пункт Add Procedure (Добавить процедуру)
из меню Tools:
Рис. 8.4
Введите в поле Name имя функции NOD, установите переключатели в положение Function и Private и нажмите клавишу “OK”. Потом введите код функции:
Private Function NOD(ByVal a As Integer, ByVal b As Integer)
Do While a <> 0 and b <> 0
If a > b Then a = a mod b Else b = b mod a
Loop
NOD = a + b
End Function
Введите следующий код для текстового окна TxtChislo1:
Private Sub TxtChislo1_KeyPress(KeyAscii As Integer)
Dim x As Integer, y As Integer
If KeyAscii = 13 Then
x = Val(TxtChislo1.Text)
y = Val(TxtChislo2.Text)
TxtNOD.Text = NOD(abs(x),abs(y))
End If
End Sub
Создайте аналогичный код для второго текстового поля.
Введите следующий код для кнопки:
Private Sub СmdExit_Click()
End
End Sub
5. Сохранение проекта
Сохраните форму и проект под именами НОД.frm и НОД.vbp.
6. Тестирование приложения
Запустите программу.
Обратите внимание, что НОД вычисляется только тогда, когда вы нажимаете клавишу Enter.
7. Модификация кода
Код, реагирующий на событие KeyPress, одинаков для первых двух текстовых полей. Создайте процедуру общего назначения, которой могут совместно пользоваться две событийные процедуры.
