- •4. Структурированные типы данных
- •4.1. Массивы
- •4.1.1. Задание массивов
- •4.1.2. Обработка массивов.
- •4.1.3. Операторы блока данных и чтения из блока данных в языке Бейсик
- •4.1.4. Типизированные константы в языке Паскаль
- •4.2. Символьный и строковый типы данных.
- •4.2.1. Описание символьного и строкового типа данных.
- •4.2.2. Операции над строками.
- •3. Принцип модульности.
- •3.1. Процедуры.
- •3.2. Функции.
- •3.3. Параметры-процедуры и параметры-функции. Процедурный тип.
- •3.4. Длинная арифметика.
- •4. Рекурсия.
- •4.1. Понятие рекурсии.
- •4.2. Формы рекурсий.
- •5. Модули в языке turbo pascal. Модуль пользователя.
- •5.1. Стандартные модули.
- •5.2. Модуль пользователя.
- •6. Обзор графических возможностей языков высшего уровня.
3. Принцип модульности.
В практике программирования достаточно часто встречаются алгоритмы, в которых повторяются фрагменты, одинаковые по выполняемым действиям и различающиеся только значениями обрабатываемых данных. При составлении программы по такому алгоритму приходится задавать одну и ту же группу операторов соответственно для каждого из повторяющихся фрагментов. Для более эффективного программирования подобных алгоритмов в языках вводится понятие подпрограммы. Повторяющаяся группа операторов оформляется в виде самостоятельной программной единицы со своими входными и выходными данными – подпрограммы, записывается однократно, а в соответствующих местах программы обеспечиваются лишь обращения к ней (ссылки) и передача данных.
Использование подпрограмм позволяет улучшить структуру программы, делает ее более компактной и наглядной, облегчает процесс проектирования, разработки и отладки программы. В языках Бейсик и Паскаль подпрограммы реализуются в виде процедур и функций, которые вводятся в программу с помощью своего описания.
Подпрограммы, а в дальнейшем и модули, должны обладать всеми свойствами алгоритма (Часть 1). Помимо этих свойств, алгоритмический модуль (АМ - совокупность предписаний в виде отдельного алгоритма) должен обладать и другими:
-
функциональная завершенность (АМ должен представлять собой логически завершенную последовательность предписаний, необходимых для решения подзадачи в рамках общей задачи).
-
минимизация связей (АМ и основная программа должны быть связаны между собой только с помощью параметров).
-
независимость (результаты работы модулей должны зависеть не от реализации других модулей, а только от входных данных).
В работе с АМ должен действовать принцип «черного ящика», т.е. известен только закон задачи, но не важен алгоритм ее решения. Существуют также принципы «серый ящик» (частичное использование глобальных объектов) и «прозрачный ящик».
3.1. Процедуры.
Описание процедуры в языке QBasic:
<процедура QBasic> ≡ SUB <идентификатор> [(<список формал. параметров>)]
<оператор>
{<оператор>}
END SUB
<Идентификатор> - это имя процедуры, которое формируется по тем же правилам, что и имена переменных.
<список формал. параметров> ≡ <идентификатор> [()] AS <тип>{, <идентификатор> [()] AS <тип>}
Все переменные, которые используются при описании процедуры, можно разделить на два вида: локальные и глобальные.
Локальные переменные действуют только внутри тела процедуры и не доступны за ее пределами. По умолчанию все переменные в процедуре являются локальными.
Глобальные переменные имеют одинаковый смысл как внутри процедуры, так и в основной программе
Если описание процедуры в программе на языке Бейсик помещается после окончания основной программы, то заголовок процедуры может быть объявлен в начале программы с помощью оператора объявления процедуры или функции, имеющего вид:
DECLARE SUB <идентификатор> [(<список формальных параметров>)]
где <список формальных параметров> содержит имена аргументов процедуры с указанием их типов.
Вызов процедуры в Бейсике производится оператором:
CALL <идентификатор> [(<список фактических параметров>)]
При вызове <идентификатор> должен соответствовать имени вызываемой процедуры из оператора SUB. <Список фактических параметров> - это последовательность разделенных запятыми переменных, при значении которых необходимо выполнить процедуру. После имени массива обязательно указываются скобки. Между фактическими и формальными параметрами должно быть установлено взаимно однозначное соответствие: число и типы параметров должны совпадать.
Обмен данными между программой и подпрограммой осуществляется, как правило, через аппарат формальных и фактических параметров. Параметры процедуры или функции могут быть следующего вида:
Параметры-значения используются для определения исходных данных процедуры и аргументов функции, в списке формальных параметров перечисляются через запятую с обязательным указанием их типа. Параметры-переменные используются для определения результатов выполнения процедуры и в списке формальных параметров (на Паскале) помещаются после служебного слова Var. В заголовке функции параметры-переменные обычно не используются, так как вычисляемое значение функции возвращается не через параметры. При описании формальных параметров в языке Паскаль следует соблюдать следующие правила:
-
Если несколько формальных параметров имеют один и тот же тип, имя типа можно указать один раз на всю группу, перечислив параметры через запятую.
-
Слово Var необходимо указывать для каждой группы параметров-переменных.
-
Тип формального параметра может быть стандартным или ранее объявленным типом, в заголовке подпрограммы нельзя вводить новый тип.
-
Компоненты записи не могут подставляться на место формальных параметров-переменных.
-
Файловые переменные должны соответствовать параметрам-переменным.
В качестве фактического параметра-значения может быть использовано выражение соответствующего типа, в частном случае – константа или переменная. При вызове подпрограммы вычисляется значение фактического параметра, полученный результат копируется во временную память и передается подпрограмме. В процессе выполнения подпрограммы параметр-значение может изменяться, но эти изменения никак не воспринимаются вызывающей программой, так как изменяется копия фактического параметра. Поэтому параметры-значения нельзя использовать для возврата результатов выполнения процедуры!
Фактический параметр-переменная может быть только переменной или типизированной константой соответствующего типа. При обращении к процедуре осуществляется передача адреса фактического параметра. Следовательно, подпрограмма имеет доступ непосредственно к фактическому параметру и может его изменять. Поэтому параметры-переменные используют при обозначении результатов работы процедуры, а также в случаях, когда параметр одновременно является входным и выходным. (Параметры-переменные передаются ссылкой.)
Обсудим случай, когда в качестве исходных данных в подпрограмму передается переменная структурированного типа, например имя массива. Определение ее как параметра-значения приведет при работе подпрограммы к созданию копии исходного массива. Можно определить ее как параметр-переменную, в этом случае копия исходного массива не создается, что повышает быстродействие и экономит память. Однако при такой передаче параметра (массива) возможно его нежелательное изменение в подпрограмме. В этой ситуации параметр (массив) лучше определить как параметр-константу; такой параметр, если он структурированного типа, передается своим адресом, но при этом предусматривается защита от его изменения в подпрограмме.
Параметр-константа описывается в заголовке подпрограммы аналогично параметру-значению, но после служебного слова Const. При вызове подпрограммы в качестве фактического параметра-константы можно использовать любое выражение соответствующего типа, в частном случае константу или переменную.
Параметр-константу нельзя передавать в другую подпрограмму в качестве фактического параметра!
Процедура аналогично программе состоит из заголовка и блока, содержащего, в свою очередь, раздел локальных описаний и раздел операторов процедуры.
Описание процедуры в языке Turbo Pascal:
<процедура TPascal> ≡ PROCEDURE <идентификатор> [(<список формал. параметров>)];
<блок>;
<Идентификатор> – это имя процедуры.
<список формал. параметров> ≡ (<парам. значение>|<парам. переменная>|<парам. процедурного типа>) {,(<парам. значение>|<парам. переменная>|<парам. процедурного типа>)}
<парам. значение> ≡ <идентификатор> {, <идентификатор>}: <тип>
<парам. переменная> ≡ VAR <идентификатор> {, <идентификатор>}: <тип>
Чтобы использовать процедуру (а также и функцию) в языке Паскаль, необходимо в разделе описаний программы поместить описание процедуры (функции), а в нужном месте исполняемой части программы указать обращение к ней. Для вызова процедуры используется оператора вызова процедуры, имеющего следующий вид:
<идентификатор> [(<список фактических параметров>)]
где <идентификатор> - имя процедуры, к которой происходит обращение; <список фактических параметров> - перечень конкретных значений (выражений) и имен, подставляемых на место формальных параметров процедуры при каждом ее вызове и выполнении.
В блок-схеме вызов процедуры обозначается следующим образом:
Где PROC – идентификатор процедуры, а A, B, … – передаваемые параметры.
Пример 3.1.1.
Составим программу, вычисляющую степень числа А с целым показателем N.
Y – результат возведения в степень
X, K, P – формальные параметры
I – вспомогательная переменная
Программа на QBasic:
SUB St (X AS SINGLE, K AS INTEGER, P AS SINGLE)
DEFINT I
P = 1
FOR I = 1 TO K
P = P*X
NEXT I
END SUB
DIM A AS SINGLE, N AS INTEGER, Y AS SINGLE
INPUT “Введите основание и показатель: ”; A, N
IF N>0 THEN
CALL St (A, N, Y)
ELSE
IF N<0 THEN St (1/A, -N, Y) ELSE Y = 1
END IF
PRINT A; “ в степени ”; N; “ = “; Y
END
Программа на TPascal:
VAR
A,Y: REAL;
N: INTEGER;
PROCEDURE St (X: REAL; K: INTEGER, VAR Y: REAL);
VAR
I: INTEGER;
BEGIN
P:= 1;
FOR I:= 1 TO K DO
P:= P*X
END;
BEGIN
WRITE (‘Введите основание и показатель: ‘);
READLN (A, N);
IF N>0 THEN
St (A, N, Y)
ELSE
IF N<0 THEN St (1/A, -N, Y) ELSE Y:= 1;
WRITELN (A, ‘ в степени ‘, N, ‘ = ‘, Y)
END.