Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Основные положения процедурного программирования
Главной проблемой структурного программирования и алгоритмических языков первых поколений стало отсутствие языковых средств структурирования исходного текста и, как следствие, крайне большая избыточность кода программ. Решением этих задач стало введение в языки программирования понятия подпрограммы как фундаментального средства ее структурирования. Подпрограмма – это средство представления исходного кода в виде логически связанных, но самостоятельных программных единиц, каждая из которых решает небольшую специфическую алгоритмическую задачу. Подпрограммы в общем случае бывают двух видов: процедуры (procedure) и функции (function). Подпрограмма представляет собой особым образом оформленный фрагмент исходного кода, имеющий собственный идентификатор, ограничивающий область видимости своих внутренних объектов. Упоминание идентификатора подпрограммы в исходном тексте приводит к активизации подпрограммы и называется ее вызовом (call). Сразу после активизации подпрограммы, распределяется память под ее внутренние переменные и начинают выполнятся входящие в нее операторы. После окончания выполнения последнего из них управление передается обратно в точку вызова подпрограммы (invocation point) и продолжают выполняются операторы, стоящие непосредственно за оператором вызова подпрограммы (рис. 13). Подпрограмма может быть вызвана из других фрагментов кода множество раз. При этом ее код не копируется в точку вызова и существует в единственном экземпляре, что позволяет существенным образом сократить объем программы, путем выделения в ней некоторого количества подпрограмм. Для обмена информацией между основной программой и подпрограммой используется один или несколько параметров вызова (call parameter). Параметр представляет собой некоторое значение, которое передается в подпрограмму и используется в ней посредством своего идентификатора. Синтаксически передача параметров выражается путем указания в операторе вызова после имени подпрограммы непосредственных значений параметров (в виде литералов) или идентификаторов переменных, которые задают значение этих параметров. Процедура – это подпрограмма, которая не возвращает слева от себя какое-либо значение и применяется для выполнения некоторых алгоритмических действий. В следующем примере показан вызов процедуры, первый параметр в которую передается в виде непосредственного значения, а второй в виде переменной:
// вызов процедуры DoSomething DoSomething (12, x); // Pascal
Параметры передаваемые в виде переменных могут быть использованы для передачи значения из вызываемой подпрограммы в вызывающую.
Рис. 13. Схематичная модель вызова подпрограммы
Напротив, функция, подобно переменной, может участвовать в выражениях и возвращает слева от себя некоторое значение заданного в ее определении типа.
// вызов функции sin, возвращающая значение вещественного типа y := sin(10 * x + 10); // Pascal
Наряду с подпрограммой, другим важным понятием в парадигме процедурного программирования является принятие программного модуля (program module). Характерным для всех современных ЯП является то, что элементарные строительные блоки программы, представляющие собой простые и структурные операторы должны быть объединены в программу посредством структурных элементов следующего уровня. Таким элементом являются подпрограммы. В свою очередь подпрограммы включаются в состав модулей, которые и являются основной структурной единицей декомпозиции программы. Программа или говорят проект, в целом, конструируется из таких модулей исходного кода. Программный модуль является средством структуризации программного проекта в целом. В самом общем случае, модуль предназначен для инкапсуляции (encapsulation), т.е. размещения внутри себя, набора из нескольких подпрограмм. Подпрограммы размещаются в модуле либо по признаку решения однотипных задачи, например, модуль с подпрограммами для обработки строк, модуль подпрограмм для работы с датами или модуль с математическими подпрограммами, либо модуль содержит в себе подпрограммы, реализующие части одной крупной алгоритмической задачи. На уровне программного модуля в ЯП определено понятие видимости (visibility) подпрограммы, которое регламентирует доступность подпрограммы из других модулей программного проекта. Подпрограммы так же, как и переменные, объявленные в модуле, в самом простейшем случае могут быть либо доступны только внутри модуля (private) или доступны как внутри, так и вне модуля, т.е. в других модулях проекта (public). Физически модуль программы представляет собой файл с исходным тестом подпрограмм, он имеет имя, на основании которого на подпрограммы внутри него ссылаются другие модули. Подробно остановимся на синтаксической реализации подпрограмм в алгоритмических языках программирования.
Реализация процедурного программирования в Visual Basic
В языке VB процедура начинается с обязательного ключевого слова SUB за которым следует идентификатор процедуры и список параметров. Формат объявления процедуры в VB имеет следующий вид:
[Private | Public] Sub <procname> [(<param_1> As <type>, … <param_n>] As <type>) [<statements>] [Exit Sub] [<statements>] End Sub
Необязательные ключевые слова PRIVATE и PUBLIC определяют область видимости процедуры в рамках программного проекта. Подпрограммы в смысле видимости могут быть открытыми или закрытыми. Открытые подпрограммы отмечаются ключевым словом PUBLIC, а закрытые PRIVATE. Область видимости закрытой подпрограммы ограничена модулем программного проекта, то есть вызов процедуры возможет только в других подпрограммах этого модуля. Напротив, открытые подпрограммы видимы и доступны в рамках программного проекта в целом, то есть в любом модуле программы. Идентификатор процедуры подчиняется тем же правилам ЯП, что и другие идентификаторы. Процедура может не иметь параметров, но если они имеются, то должны быть перечислены в скобках. Перечисление формальных параметров, выступает подобно внутренним переменным и служит для прохождения из вызывающей подпрограммы значений или как говорят фактических параметров. Приведем пример простой процедуры на VB:
Public Sub MyFirstProc(AParam as Integer) Dim sMessage as String If AParam = 0 then sMessage = "Hello world" Else sMessage = "Good bye, world" End if For I = 0 to 9 Debug.Print sMessage Next End Sub Как видно из примера подпрограмма проявляет себя как небольшая программа, внутри которой возможно использование всех языковых средств языка: структурных и простых операторов, объявлений переменных и вызов других подпрограмм. Вызов процедуры из другой части программы осуществляется с помощью ключевого слова CALL за которым следует имя процедуры и в скобках список фактических параметров:
Call MyFirstProc (0)
Ключевое слово CALL может быть пропущено, но тогда список фактических параметров должен быть указан без скобок:
MyFirstProc 0
Любая процедура может быть объявлена и без формальных параметров, тогда она не может получать информацию извне, как только с помощью специальных переменных объявленных на уровне модуля или глобальных переменных. В следующем примере показан способ передачи информации в подпрограммы с использованием переменной, объявленной на уровне модуля. Такая переменная разделяется всеми подпрограммами данного модуля и ее значение может быть доступно любой процедуре или функции в любой момент времени.
Private x As Integer
Sub ParamFreeProc() x = x + 10 End Sub
Sub CallingRoutine() x = 10 ParamFreeProc Debug.Print x End Sub
Однако такой способ передачи информации сводит на нет преимущества и основную идею процедурной парадигмы программирования – сокрытие внутренней информации от других алгоритмических процессов. Одним из свойств параметров является способ их передачи в подпрограмму. В VB возможно два типа прохождения параметра: по ссылке, что используется по умолчанию и по значению. Тип прохождения параметра задается перед идентификатором формального параметра с помощью ключевых слов BYREF (по ссылке) или BYVAL (по значению). При передаче параметра по ссылке его измененное значение внутри подпрограммы может быть доступно из вызывающей подпрограммы например:
Public Sub MyFirstProc(ByRef AParam as Integer) AParam = AParam * 100 End Sub
Public Sub MySecondProc Dim Param as Integer Param = 10 MyFirstProc Param Debug.Print Param ' значение Param равно 1000 End Sub
Это связано с тем, что при прохождении параметра по ссылке в вызываемую процедуру передается не значение переменной, а ее адрес, и значение по этому адресу становится доступным для изменения. Ячейка памяти по этому адресу становиться доступной как в вызываемой, так и вызывающей процедурах. Напротив, при передаче по значению в вызывающую процедуру передается не адрес, а значение, которое копируется по новому адресу внутри процедуры. Таким образом, содержимое передаваемого параметра по значению локализуется в вызываемой подпрограмме. Например:
Public Sub MyFirstProc(ByVal AParam as Integer) AParam = AParam * 100 End Sub
Public Sub MySecondProc Dim Param as Integer Param = 10 MyFirstProc Param Debug.Print Param ‘ значение Param равно 10 End Sub
С подпрограммами также связано такое важное понятие в программировании как область видимости и время жизни (life time) переменной. Если переменная объявлена в теле подпрограммы с помощью ключевого слова DIM, ее значение теряется при окончании работы подпрограммы. При этом говорят, что областью видимости переменной является подпрограмма, а временем ее жизни – время исполнения подпрограммы. При объявлении внутренней переменной с помощью ключевого слова STATIC ее значение сохраняется между вызовами подпрограммы. Например:
Public Sub MyStaticProc() Static X As Integer Param = X + 10 Debug.Print X End Sub Public Sub MyOrdinaryProc() Dim X As Integer Param = X + 10 Debug.Print X End Sub
Повторный вызов первой процедуры приводит к тому, что статическая переменная X с каждым вызовом увеличивает свое значение на 10. Тогда как многократный вызов второй подпрограммы не изменяет значения ее локальной переменной. Таким образом, всякая переменная объявленная в подпрограмме имеет область видимости ограниченную этой подпрограммой. Однако время жизни статической переменой не ограничено промежутком времени в котором исполняются операторы подпрограммы, и существует до тех пор пока работает программа (адрес переменной не потерян), даже несмотря на то, что видима статическая переменная также только в области подпрограммы. Если перед ключевым словом SUB указано ключевое слово STATIC, тогда все без исключения локальные переменные процедуры становиться статическими независимо от того, как они объявлены. В противоположность внутренним локальным переменным подпрограмм все переменные объявленные вне их области видимости, т.е. на уровне модуля имеют время жизни ограниченное только временем исполнения программы. Переменная объявленная на уровне модуля с использования ключевого слова DIM становиться закрытой переменной, также как если бы она была объявлена с помощью ключевого слова PRIVATE
′Закрытые переменные модуля Private x As Integer Dim a As Integer
Для того чтобы объявить переменную доступную в других модулях проекта используется ключевое слово PUBLIC
′ Открытая переменная Public s As Integer
В ходе своей работы процедура может досрочно завершить свое исполнение и передать управление в точку вызова. Для этого в теле процедуры может быть указан специальный оператор завершения – EXIT SUB. Например:
Sub ExitFromProc(ByRef a As Integer) If a > 50 Then Exit Sub End If a = a + 1 End Sub Все сказанное выше для процедур справедливо и для другого вида подпрограммам – функций. Однако, в отличие от процедур функция имеет возможность возвращать слева от себя значение скалярного или структурного типа. Объявляется функция аналогичным образом процедуре, однако в объявлении функции может быть указан, хотя это и необязательно, тип возвращаемого функцией значения после ключевого слова AS, которое следует за списком параметров функции.
[Public | Private] [Static] Function <namefunc> [(arglist)] [As type] [<statements>] End Function
В области видимости любой функции, в отличие от процедуры, неявно определена переменная одноименная идентификатору функции и имеющая тот же тип, что и возвращаемое функцией значение. Приведем пример функции, которая реализует отбрасывание определенного количества значащих зарядов числа с плавающей точкой. Результат выполнения функции передается вовне с помощью неявной переменной совпадающей с именем функции.
Function RoundN(x As Double, n As Byte) As Double Dim Factor As Long Factor = 10 ^ n RoundN = Fix(x * Factor) / Factor End Function Применение функций не ограничивается их использованием для реализации простейших численных алгоритмов. С помощью функций построены библиотеки подпрограмм для обработки строк, для работы с датами и др. Функции являются наиболее гибким и мощным инструментом при реализации концепции процедурного программирования и положены в основу базовых идей объектно-ориентированного программирования. Библиотека времени исполнения языка Visual Basic предоставляет в распоряжение разработчика программ широчайший набор функций и процедур, которые решают наиболее часто возникающие перед разработчиком задачи, связанные с выполнением математических операций, манипулирования строчными данными и датами. Коротко рассмотрим три эти наиважнейшие группы функций. К группе математических функций относятся следующие (табл. 5)
Таблица 5. Базовые математические функции библиотеки времени исполнения VB
Рассмотрим более подробно группу строчных функций и примеры их использования. К наиболее важным функциям в этой группе относятся функции извлечения части строки. К таким функциям принадлежат три функции Mid, Left и Right. Функция Mid извлекает некоторую часть строки <string> заданной длины <length>, начиная с некоторого символа в определенной позиции <start>:
Mid (<string>, <start>As Long [, <length>As Long]) As Variant
Функция принимает вариантное значение в качестве первого аргумента и возвращает также вариантный тип. Например:
Dim MyString, FirstWord, LastWord MyString = "Mid Function Demo" ' Определяем строку FirstWord = Mid(MyString, 1, 3) ' Возвращает "Mid". LastWord = Mid(MyString, 14, 4) ' Возвращает "Demo".
Функция Left подобно функции Mid возвращает подстроку из строки <string>, но только определенное количество символов слева, число которых указано в качестве второго аргумента <length>:
Left (<string>, <length> As Long) As Variant
Как и Mid функция Left возвращает вариантный тип данных. Приведем пример использования этой функции:
Dim AnyString, MyStr AnyString = "Hello World" ' Определяем строку MyStr = Left(AnyString, 7) ' Возвращает "Hello W".
Еще одной похожей функцией является функция Right, возвращающая заданное число символов, начиная с конца строки
Right (<string>, <length> as Long) as Variant
Для определения числа символов в строке в VB имеется функция Len:
Len (<string> | <variant>) as Long Например:
MyString = "Hello World" ' инициализация строки MyLen = Len(MyString) ' возвращает 11 К строчным функциям относится также подгруппа функций конвертирования строчных данных: Hex, UCase, LCase, LTrim, RTrim и Trim. Функция Hex возвращает строчное представление шестнадцатеричного значения целого числа.
Hex (<number> As Long) As Variant
Например:
Dim MyHex MyHex = Hex(459) ' Возвращает 1CB
Функции UCase и LCase возвращают содержимое исходной строки преобразованное в верхний или в нижний регистр символов соответственно:
UCase (<string> As Variant) As Variant LCase (<string> As Variant) As Variant
Например:
Dim AnyCase, LowerCase, UpperCase AnyCase = "Hello World 1234" ' Преобразуемая строка UpperCase = UCase(LowerCase) ' Возвращает "HELLO WORLD 1234". Lowercase = Lcase(UpperCase) ' Возвращает "hello world 1234".
На основе встроенных в библиотеку времени исполнения функций работы со строками могут быть реализованы сколь угодно сложные пользовательские функции обработки строк. Рассмотрим в качестве примера законченную пользовательскую функцию, которая выполняет подсчет числа слов входящих в строку. Функция использует несколько встроенных строчных функций для реализации своей функциональности.
Function CountWords(s) As Integer Dim WC As Integer, i As Integer, OnASpace As Integer WC = 0 ' внутренний счетчик OnASpace = True ' указание того, что встали на пробел ' сканируем все символы строки For i = 1 To Len(s) ' если встретили пробел If Mid(s, i, 1) = " " Then ' выбрасываем флаг OnASpace = True Else ' если нет, определяем был ли предыдущим пробел If OnASpace Then ' сброс флага OnASpace = False ' идет очередное слово WC = WC + 1 End If End If Next i CountWords = WC End Function
Группа функций манипулирования датами включает в себя такие функции которые позволяют формировать даты и время в программе, извлекать составные части даты и времени и выполнять простые вычисления над ними. Функция Now возвращает в виде значения вариантного типа текущую дату и время соответствующую системной дате и времени компьютера.
Dim Today As Date Today = Now
Переменные типа «дата» хранятся в виде 64-битного числа с плавающей точкой, которое представляет даты в диапазоне от 1 января 100 года до 31 декабря 9999 года. Литерал типа «дата» представляется любой последовательностью символов правильного формата заключенного между символами «#». Формат определяется установками в операционной системе. Например: #09/01/1992# . Поскольку, даты в VB храниться в виде чисел, это дает дополнительные преимущества, позволяя при необходимости обрабатывать их как числовые значения в выражениях. Например, для получения следующей даты необходимо прибавить к дате единицу:
Dim Tomorrow As Date Tomorrow = Date() + 1
Для выделения составляющих дат – года, месяца, дня – имеются функции Year, Month и Day соответственно. Например:
Dim MyBirthDay As Date Dim MyDay, MyMonth, MyYear MyBirthDay = #05/09/1975# MyDay = Day(MyBirthDay) ' 9 MyMonth = Month(MyBirthDay) ' 5 MyYear = Year(MyBirthDay) ' 1975
VB имеет также встроенную функцию DatePart, которая позволяет выбрать любую составляющую даты и времени, а также выполнить некоторые несложные вычисления
Dim MyBirthDay As Date Dim MyDay, MyMonth, MyYear MyBirthDay = #05/09/1975# MyDay = DatePart("d", MyBirthDay) MyMonth = DatePart ("m", MyBirthDay) MyYear = DatePart("yyyy", MyBirthDay)
Функции DateAdd и DateDiff, которые позволяют выполнять сложение и вычитание интервалов дат и времени. Функция DateAdd позволяет добавлять к значению даты и времени любое количество интервалов произвольной длины:
DateAdd(<Interval> As String, <Number> As Double, <Date> As Date) As Date
<Interval> – представляет собой строчную константу, задающую интервал времени, <Number> – задает количество добавляемых интервалов, как положительных, так и отрицательных, <Date> – определяет дату, к которой добавляется указанный интервал. Например, прибавить год к текущей дате можно следующим образом
DateAdd ("yyyy", 1, Date())
или прибавить два часа
DateAdd ("h", 2, Now())
Если требуется определить интервал между двумя датами в днях, месяцах, годах или других интервалах можно воспользоваться функцией DateDiff. Например, для вычисления точного значения возраста:
Dim MyBirthDay As Date Dim MyAge As Single MyBirthDay = #5/9/1975# MyAge = DateDiff("d", MyBirthDay, Now) / 365
В заключение рассмотрения основ процедурного программирования следует отметить, что в VB отсутствует возможность объявления одной подпрограммы внутри другой, т.е. вложенных подпрограмм. |
||||||||||||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 503. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |