Инструменты пользователя

Инструменты сайта


bb:redbook:107

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

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