Предыдущая версия справа и слева
Предыдущая версия
Следующая версия
|
Предыдущая версия
|
bb:redbook:107 [2017/08/30 14:28] prospero78 [5. Вызов процедуры с параметрами] |
bb:redbook:107 [2017/12/26 07:51] иван_денисов удалено |
Этот вариант программы делает всё тоже самое, что и предыдущая, но с использованием дополнительной процедуры ''Вещ_ Печать'' описанной выше. Передаваемый аргумент ''вПерем'' должен иметь тот же тип, что и требуемый параметр в объявлении процедуры. В противном случае, **КП** посчитает это ошибкой. Теперь вместо двух инструкций ''мЛог.Real(вПерем); Log.Ln'' можно писать только одну, что приводит к сокращению набираемого кода. В этом примере заключается одна из ключевых идей процедурного стиля. Но обратите внимание, что для вызова процедуры компьютеру требуется выполнить ряд дополнительный служебных действий, и при возврате из процедуры также выполняются некоторые действия, что приводит к дополнительным небольшим затратам времени. Поэтому, //вызов процедуры должен быть оправдан//. Само тело процедуры не должно состоять из одной инструкции, так как в этом //нет никакого смысла//. | Этот вариант программы делает всё тоже самое, что и предыдущая, но с использованием дополнительной процедуры ''Вещ_ Печать'' описанной выше. Передаваемый аргумент ''вПерем'' должен иметь тот же тип, что и требуемый параметр в объявлении процедуры. В противном случае, **КП** посчитает это ошибкой. Теперь вместо двух инструкций ''мЛог.Real(вПерем); Log.Ln'' можно писать только одну, что приводит к сокращению набираемого кода. В этом примере заключается одна из ключевых идей процедурного стиля. Но обратите внимание, что для вызова процедуры компьютеру требуется выполнить ряд дополнительный служебных действий, и при возврате из процедуры также выполняются некоторые действия, что приводит к дополнительным небольшим затратам времени. Поэтому, //вызов процедуры должен быть оправдан//. Само тело процедуры не должно состоять из одной инструкции, так как в этом //нет никакого смысла//. |
| |
Ещё один момент на который необходимо обратить внимание — это порядок размещения процедур. Если процедуру ''Вещ Печать'' разместить позже процедуры ''Старт'' компилятор **КП** не сможет понять, что за процедуру вызывает инструкция ''Вещ_Печать(вПерем)''. Компиляция завершится ошибкой. Поэтому, объявление процедур должно быть упреждающим. | Ещё один момент на который необходимо обратить внимание — это порядок размещения процедур. Если процедуру ''Вещ Печать'' разместить позже процедуры ''Старт'' компилятор **КП** не сможет понять, что за процедуру вызывает инструкция ''Вещ Печать(вПерем)''. Компиляция завершится ошибкой. Поэтому, объявление процедур должно быть упреждающим. |
| |
==== 6. Возврат значения из процедуры ==== | ==== 6. Возврат значения из процедуры ==== |
| |
<code oberon2> | <code oberon2> |
PROCEDURE MathLogReal (p1, p2: INTEGER): REAL; | PROCEDURE Вещ_Вычисл(пцЗнач1, пцЗнач2: INTEGER): REAL; |
VAR | VAR |
r: REAL; | вРезульт: REAL; |
BEGIN | BEGIN |
r := p1 / p2; | вРезульт := пцЗнач1 / пцЗнач2; |
Log.Real(r); | мЛог.Real(вРезульт); |
Log.Ln; | мЛог.Ln; |
RETURN r | RETURN вРезульт |
END MathLogReal; | END Вещ_Вычисл; |
</code> | </code> |
| |
Теперь процедура ''LogReal'' не только выводит значение переменной типа ''REAL'', но и может рассчитать его. Поэтому, было изменено название процедуры на ''MathLogReal''. Обратите внимание, как определены два входных параметра типа ''INTEGER'' — подряд через запятую. За списком параметров указан тип возвращаемого значения. Также впервые была использована секция процедуры ''VAR'', в которой определена переменная ''r'' типа ''REAL'', значение которой, рассчитывается внутри процедуры, и в конечном итоге возвращается. Если ключевое слово ''RETURN'' разместить перед вычислениями, то сами вычисления не будут выполнены, а в процедуру ''Start'' будет возвращено непонятно что (//мусор//). | Теперь процедура ''Вещ Печать'' не только выводит значение переменной типа ''REAL'', но и может рассчитать его. Поэтому, было изменено название процедуры на ''Вещ Вычисл''. Обратите внимание, как определены два входных параметра типа ''INTEGER'' — подряд через запятую. За списком параметров указан тип возвращаемого значения. Также впервые была использована секция процедуры ''VAR'', в которой определена переменная ''вРезульт'' типа ''REAL'', значение которой, рассчитывается внутри процедуры, и в конечном итоге возвращается. Если ключевое слово ''RETURN'' разместить перед вычислениями, то сами вычисления не будут выполнены, а в процедуру ''Старт'' будет возвращено непонятно что (//мусор//). |
| |
Полный код модифицированной программы приведён ниже: | Полный код модифицированной программы приведён ниже: |
Hello04.odc | Hello04.odc |
<code oberon2> | <code oberon2> |
MODULE TestHello04; | MODULE КнигаПривет4; |
(* это четвёртая программа на языке | (* это четвёртая программа на языке |
Компонентный Паскаль. Она выполняет | Компонентный Паскаль. Она выполняет |
которые возвращают значение *) | которые возвращают значение *) |
| |
IMPORT Log, Math; | IMPORT мЛог := Log, |
| Math; |
| |
CONST | CONST |
c = 2; | _конст = 2; |
| |
VAR | VAR |
i: INTEGER; | цПерем: INTEGER; |
i1: REAL; | вПерем: REAL; |
| |
PROCEDURE MathLogReal (p1, p2: INTEGER): REAL; | PROCEDURE Вещ_Вычисл (пцЗнач1, пцЗнач2: INTEGER): REAL; |
VAR | VAR |
r: REAL; | вРезульт: REAL; |
BEGIN | BEGIN |
r := p1 / p2; | вРезульт := пцЗнач1 / пцЗнач2; |
Log.Real(r); | мЛог.Real(вРезульт); |
Log.Ln; | мЛог.Ln; |
RETURN r | RETURN вРезульт |
END MathLogReal; | END Вещ_Вычисл; |
| |
PROCEDURE Start*; | PROCEDURE Старт*; |
VAR | VAR |
BEGIN | BEGIN |
Log.String('Привет, мир!'); Log.Ln; | мЛог.String('Привет, мир!'); мЛог.Ln; |
i := 3; | цПерем := 3; |
i1 := MathLogReal(c, i) | вПерем := Вещ_Вычисл(_конст, цПерем) |
END Start; | END Старт; |
BEGIN | BEGIN |
END TestHello04. | END КнигаПривет4. |
</code> | </code> |
Как видно из текста модуля, процедура ''Start'' стала существенно короче. Кроме того, константа ''с'' успешно передаётся в процедуру. Это говорит о том, что компилятор **КП** автоматически присвоил ей тип ''INTEGER'' (мы тип этой константы не описали). Кроме того, ни модуль, ни процедура ''Start'' не подозревают о наличии переменной ''r'' внутри процедуры ''MathLogReal''. А значит ни одна процедура модуля (и сам модуль) не могут испортить её значение. Так достигается сокрытие информации. | Как видно из текста модуля, процедура ''Старт'' стала существенно короче. Кроме того, константа ''_конст'' успешно передаётся в процедуру. Это говорит о том, что компилятор **КП** автоматически присвоил ей тип ''INTEGER'' (мы тип этой константы не описали). Кроме того, ни модуль, ни процедура ''Старт'' не подозревают о наличии переменной ''вРезульт'' внутри процедуры ''Вещ Вычисл''. А значит ни одна процедура модуля (и сам модуль) не могут испортить её значение. Так достигается сокрытие информации. |
==== 7. Экспорт процедуры ==== | ==== 7. Экспорт процедуры ==== |
Самые внимательные читатели уже обратили внимание на то, что за именем процедуры ''Start'' стоит символ (*). Этот символ как раз и указывает компилятору сделать //экспорт// процедуры из модуля. Попробуйте уберите звёздочку и скомпилируйте — вы не сможете вызвать процедуру ''Start''. После экспорта, указанная процедура может быть вызвана извне модуля. Именно поэтому её можно запустить на выполнение через ''КОММАНДЕР''. Тема экспорта //очень важна//, и в этом разделе получила лишь минимальное освещение, о других особенностях экспорта речь ещё пойдёт дальше. | Самые внимательные читатели уже обратили внимание на то, что за именем процедуры ''Старт'' стоит символ //звёздочка//. Этот символ как раз и указывает компилятору сделать //экспорт// процедуры из модуля. Попробуйте уберите звёздочку и скомпилируйте — вы не сможете вызвать процедуру ''Старт'' . После экспорта, указанная процедура может быть вызвана извне модуля. Именно поэтому её можно запустить на выполнение через ''КОММАНДЕР''. Тема экспорта //очень важна//, и в этом разделе получила лишь минимальное освещение, о других особенностях экспорта речь ещё пойдёт дальше. |
==== 8. Заключение ==== | ==== 8. Заключение ==== |
В этой части учебника были рассмотрены в первом приближении очень важные положения КП процедурного стиля: | В этой части учебника были рассмотрены в первом приближении очень важные положения **КП** процедурного стиля: |
- Как объявить процедуру | - Как объявить процедуру |
- Как объявить входные параметры процедуры | - Как объявить входные параметры процедуры |