Шаг 65.
Организация процедур и функций

    На этом шаге мы рассмотрим правила организации процедур и функций.

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

    VBScript предусматривает создание двух типов подпрограмм:

    Процедура Sub выполняет последовательность действий, но не возвращает никакого значения. Ее синтаксис следующий:

Sub <имя процедуры> (<необязательный список параметров>)
<операторы процедуры> 
End Sub

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

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

Call MyProc(firstarg, secondarg) 
MyProc firstarg, secondarg

    Функция также выполняет определенную последовательность операторов и ей можно передать внешние данные через параметры процедуры, но, в отличие от процедуры Sub, она возвращает значение, присваиваемое ее имени, которое может быть использовано в выражениях VBScript. Она имеет следующий синтаксис:

Function <имя функции> (<необязательный список параметров>)
<операторы процедуры> 
<имя функции> = <возвращаемое значение>
End Function

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

    Приведем пример использования процедур и функций.


Задание. Создать HTML-документ, запрашивающий 2 целых числа и выводящий их сумму, причем вычисление суммы чисел и вывод результата должен осуществляться в отдельной процедуре.

    Текст HTML-документа, решающего эту задачу, может быть следующим.

<HTML>
<HEAD>
<TITLE>Пример №1</TITLE>
<SCRIPT LANGUAGE=VBScript>
<!--
'Процедура вычисления суммы.
'Она имеет два параметра.
Sub Summa (X, Y)
  Dim Z
  Z = CInt(X) + CInt(Y)
  Alert "Их сумма = "&Z
End Sub

Sub Button1_OnClick()
  A = InputBox("Задайте 1-е число", "Ввод исходных данных", "3", 100, 100)
  B = InputBox("Задайте 2-е число", "Ввод исходных данных", "4", 100, 100)
  'Обращение к процедуре.
  Call Summa(A,B)
End Sub
'-->
</SCRIPT>
</HEAD>
<BODY>
По нажатию кнопки запрашиваются два числа и выводится их сумма. 
Все расчеты и вывод результата осуществляется в отдельной процедуре.
<FORM>
<INPUT TYPE="BUTTON" NAME="BUTTON1" Value="Вперед">
</FORM>
</BODY>
</HTML>

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


Рис.1. Результат просмотра в браузере

Текст этого документа можно взять здесь.

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

    В заключение остановимся на способах передачи параметров в подпрограммы.

    VBScript предоставляет два способа передачи параметров в подпрограммы:

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

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

    Проиллюстрируем это на следующем примере.


Задание 2. Создайте HTML-документ, при просмотре которого в браузере запрашиваются два числа, после чего происходит обмен значениями переменных при выполнении процедуры.
<HTML>
<HEAD>
<TITLE>Пример №1</TITLE>
<SCRIPT LANGUAGE=VBScript>
<!--
'Процедура обмена значениями двух переменных.
Sub Obmen (X, Y)
  Dim T
  T = X
  X = Y
  Y = T
End Sub

Sub Button1_OnClick()
  A = InputBox("Значение переменной A", "Ввод исходных данных", "-2", 100, 100)
  B = InputBox("Значение переменной B", "Ввод исходных данных", "5", 100, 100)
  Alert "Значения до обмена: A="&A&" "&"B="&B
  'Обращение к процедуре.
  Obmen A,B
  Alert "Значения после обмена: A="&A&" "&"B="&B
End Sub
'-->
</SCRIPT>
</HEAD>
<BODY>
По нажатию кнопки запрашиваются два числа и происходит обмен 
значениями этих переменных.Обмен осуществляется в отдельной процедуре.
<FORM>
<INPUT TYPE="BUTTON" NAME="BUTTON1" Value="Вперед">
</FORM>
</BODY>
</HTML>

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


Рис.2. Результат просмотра в браузере

Текст этой программы можно взять здесь.

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

Sub Obmen (ByVal A, ByVal B)

то обмена значениями не происходит! Дело в том, что наличие служебного слова ByVal приводит к отправке в подпрограмму копий значений параметров (в нашем случае – значений переменных A и B). Поэтому в самой подпрограмме изменяются копии, а не сами значения!

    На следующем шаге мы рассмотрим условные конструкции




Предыдущий шаг Содержание Следующий шаг