Ada (798525), страница 12
Текст из файла (страница 12)
В качестве фактического параметра подпрограммы можетбыть передано целое выражение, при этом режимом передачи параметра не может быть режим "out".Каждый формальный параметр подпрограммы имеет имя, тип и режим передачи.Подпрограммы могут содержать локальные описания типов, подтипов, переменных, констант,других подпрограмм и пакетов.Подпрограмма Ады, как правило, состоит из двух частей: спецификации и тела. Спецификацияописывает интерфейс обращения к подпрограмме, другими словами - "что" обеспечиваетподпрограмма. Тело подпрограммы описывает детали реализации алгоритма работыподпрограммы, то есть, "как" подпрограмма устроена.Разделение описания подпрограммы на спецификацию и тело не случайно, и имеет большоезначение. Такой подход позволяет предоставить пользователю подпрограммы только ееспецификацию и оградить, и даже избавить его от деталей реализации подпрограммы.Однажды скомпилированная и сохраненная в атрибутивном файле спецификация может бытьпроверена на совместимость с другими подпрограммами (и пакетами) когда они будуткомпилироваться.
Таким образом, при проектировании, мы можем представить толькоспецификацию подпрограммы и передать ее компилятору. При предоставлении большогоколичества фиктивных подпрограмм-заглушек (stubs) мы можем осуществлять предварительноетестирование проекта всей системы и обнаруживать любые ошибки проектирования до того какбудет потрачено много усилий на реализацию конкретных решений (идеи данного подходарассматриваются также при обсуждении концепции пакетов).Необходимо заметить, что спецификации подпрограмм, как правило, помещаются вспецификации пакетов, а тела подпрограмм - в тела пакетов.Кроме того, подпрограмма может быть самостоятельным независимым программным модулем.В этом случае, спецификация и тело подпрограммы помещаются в разные файлы (в файлспецификации и в файл тела, соответственно).
Следует также заметить, что помещатьспецификацию в отдельный файл, когда подпрограмма не является самостоятельной единицейкомпиляции не обязательно. В этом случае, спецификация подпрограммы может отсутствовать.6.1.1 ПроцедурыПроцедуры Ады подобны процедурам Паскаля и используются для реализации самыхразнообразных алгоритмов.Общий вид описания процедуры выглядит следующим образом:procedure имя_процедуры [ (формальные_параметры) ] ;спецификация процедуры, определяющая имя процедуры и профиль ееформальных параметров (если они есть)Общий вид тела процедуры:procedure имя_процедуры [ (формальные_параметры) ] isспецификация процедуры, определяющая имя процедуры и профиль ееформальных параметров (если они есть).
. .описательная (или декларативная) часть, которая может содержатьлокальные описания типов, переменных, констант, подпрограмм.... . .исполняемая часть процедуры, которая описывает алгоритм работыпроцедуры;обязана содержать хотя бы одну инструкциюbeginend [ имя_процедуры ];здесь, указание имени процедуры опциональноТаким образом, описание содержит только спецификацию процедуры и определяет правила еевызова (иначе - интерфейс), а тело содержит спецификацию и последовательность инструкций,которые выполняются при вызове процедуры.Примечательно требование Ады, чтобы исполняемая часть процедуры содержала хотя бы однуинструкцию. Поэтому, как правило на этапе проектирования, при написании процедур-заглушекиспользуется пустая инструкция, например:procedure Demo(X: Integer; Y: Float) isbeginnull; -- пустая инструкцияend Demo;Вызов процедуры производится также как и в языке Паскаль, например:Demo(4, 5.0);Необходимо также заметить, что Ада предоставляет программисту возможность, принеобходимости, помещать в любых местах внутри исполнительной части процедурыинструкцию возврата из процедуры - return.6.1.2 ФункцииФункции во многом подобны процедурам, за исключением того, что они возвращают значение ввызвавшую их подпрограмму.
Также можно сказать, что функция - это подпрограмма котораяосуществляет преобразование одного или нескольких входных значений в одно выходноезначение.Общий вид описания функции выглядит следующим образом:function имя_функции [ (формальные_параметры) ]return тип_возвращаемого_значения ;спецификация функции, определяющая имя функции, профиль ее формальныхпараметров (если они есть) и тип возвращаемого значенияОбщий вид тела функции:function имя_функции [ (формальные_параметры) ]return тип_возвращаемого_значения is.
. .спецификация функции, определяющая имя функции, профиль ее формальныхпараметров (если они есть) и тип возвращаемого значенияописательная (или декларативная) часть, которая может содержать локальныеописания типов, переменных, констант, подпрограмм...begin. . .исполнительная часть функции, которая описывает алгоритм работы функции;обязана содержать хотя бы одну инструкцию возврата значения - returnend [ имя функции ];здесь, указание имени функции опциональноИспользование инструкции возврата значения - return очень похоже на то, что используется вязыке Си, при этом, функция может иметь сколько угодно инструкций возврата значения.Функция может быть вызвана как часть выражения в инструкции присваивания или какаргумент соответствующего типа при вызове другой функции или процедуры.
Другими словами- функция, возвращающая значения заданного типа, может быть использована везде, где можетбыть использована переменная этого типа.Хотя режимы передачи параметров в подпрограммы будут подробно рассмотрены несколькопозже, здесь, необходимо сделать несколько важных замечаний, которые имеют значение дляфункций Ады.Согласно традиций стандарта Ada83, для передачи параметров в функцию разрешаетсяиспользовать только режим "in".
Поэтому, функция, через свои параметры, может толькоимпортировать данные из среды вызвавшей эту функцию. При этом, параметры функции немогут быть использованы для изменения значений переменных в среде вызвавшей функцию.Таким образом, в отличие от традиций языка Си, функции Ады не обладают побочнымиэффектами.Стандарт Ada95 ввел новый режим для передачи параметров - access. Этот режим разрешаетсяиспользовать для передачи параметров в функции. Следует заметить, что использование этогорежима допускает написание функций обладающих побочными эффектами.6.1.3 Локальные переменныеКак уже говорилось, подпрограммы (и процедуры, и функции) могут содержать локальныепеременные. Такие переменные доступны только внутри подпрограммы и не видимы извне этойподпрограммы.
Время жизни (время существования) таких переменных определяется временемжизни (временем выполнения) подпрограммы.Во время работы программы, при входе в подпрограмму, имеющую локальные переменные, встеке времени выполнения происходит автоматическое распределение пространства длялокальных переменных данной подпрограммы. При выходе из подпрограммы пространствостека времени выполнения, распределенное для локальных переменных данной подпрограммы,автоматически возвращается системе.6.1.4 Локальные подпрограммыТакже как и Паскаль, и в отличие от Си, Ада позволяет встраивать одни подпрограммы в другиеподпрограммы, конструируя один общий компилируемый модуль.
Другими словами,подпрограмма Ады может содержать внутри себя вложенные подпрограммы, которые не будутвидимы извне этой подпрограммы. К таким локальным подпрограммам можно обращатьсятолько из подпрограммы которая их содержит.with Ada.Text_IO;with Ada.Integer_Text_IO;use Ada.Text_IO;use Ada.Integer_Text_IO;procedure Ive_Got_A_Procedure isX : Integer := 6;Y : Integer := 5;procedure Display_Values (Number : Integer) isbeginPut (Number);New_Line;end Display_Values;beginDisplay_Values (X);Display_Values (Y);end Ive_Got_A_Procedure;В этом примере область видимости процедуры Display_Values ограничивается процедуройIve_Got_A_Procedure. Таким образом, процедура Display_Values "не видна" и неможет быть вызвана из любого другого места.6.1.5 Раздельная компиляцияВ предыдущем примере, если будет произведено какое-нибудь изменение кода, то обепроцедуры должны быть переданы компилятору (поскольку обе находятся в одном файле сисходным текстом).
Мы можем разделить эти две компоненты, и поместить их в отдельныефайлы, оставляя без изменения ограничения области видимости для процедурыDisplay_Values. Это несколько похоже на директиву #include, используемую в языке Си,но, в языке Ада, теперь оба файла становятся независимыми компилируемыми модулями.В первом файле:with Ada.Text_IO;use Ada.Text_IO;with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;procedure Ive_Got_A_Procedure isX : Integer := 6;Y : Integer := 5;procedure Display_Values(Number : Integer) is separate;beginDisplay_Values(X);Display_Values(Y);end Ive_Got_A_Procedure;Во втором файле:separate(Ive_Got_A_Procedure)-- примечание! нет завершайщего символа-- точки с запятойprocedure Display_Values(Number : Integer) isbeginPut(Number);New_Line;end Display_Values;Выделенный в самостоятельный файл (и ставший отдельно компилируемым модулем), код идентичен тому, что было в предыдущей версии.