Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Основные положения процедурного программирования




 

Главной проблемой структурного программирования и алгоритмических языков первых поколений стало отсутствие языковых средств структурирования исходного текста и, как следствие, крайне большая избыточность кода программ. Решением этих задач стало введение в языки программирования понятия подпрограммы как фундаментального средства ее структурирования. Подпрограмма – это средство представления исходного кода в виде логически связанных, но самостоятельных программных единиц, каждая из которых решает небольшую специфическую алгоритмическую задачу. Подпрограммы в общем случае бывают двух видов: процедуры (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>]
[Exit Function]
[<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

Обозначение Описание
Abs (<number>) Возвращает абсолютное значение числа. В качестве фактического параметра может быть указано любой выражение возвращающее числовое значение. Если параметр принимает значение NULL, то результатом функции является также значение NULL.
Atn(<number>)   Возвращает число с плавающей точкой типа DOUBLE равное арктангенсу аргумента number. Функция возвращает угол в радианах в диапазоне от –π/2 до + π/2.
Cos(<number>), Sin(<number>),  Tan(<number>) Возвращают значение типа DOUBLE, соответствующее значению тригонометрических функций косинуса, синуса и тангенса.
Sqr(<number>) Возвращает значение квадратного корня их аргумента. 
Exp(<number>) Возвращает значение экспоненциальной функции.
Log(<number>) Возвращает значение логарифмической функции.
Rnd(<number>) Возвращает случайное число с плавающей точкой в диапазоне от 0 до 1.

 

Рассмотрим более подробно группу строчных функций и примеры их использования. К наиболее важным функциям в этой группе относятся функции извлечения части строки. К таким функциям принадлежат три функции 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; просмотров: 441.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...