Подпрограмма

Поделись знанием:
Перейти к: навигация, поиск

Подпрограмма (англ. subroutine) — поименованная или иным образом идентифицированная часть компьютерной программы, содержащая описание определённого набора действий. Подпрограмма может быть многократно вызвана из разных частей программы. В языках программирования для оформления и использования подпрограмм существуют специальные синтаксические средства.





Назначение подпрограмм

Подпрограммы изначально появились как средство оптимизации программ по объёму занимаемой памяти — они позволили не повторять в программе идентичные блоки кода, а описывать их однократно и вызывать по мере необходимости. К настоящему времени данная функция подпрограмм стала вспомогательной, главное их назначение — структуризация программы с целью удобства её понимания и сопровождения.

  • Выделение набора действий в подпрограмму и вызов её по мере необходимости позволяет логически выделить целостную подзадачу, имеющую типовое решение. Такое действие имеет ещё одно (помимо экономии памяти) преимущество перед повторением однотипных действий: любое изменение (исправление ошибки, оптимизация, расширение функциональности), сделанное в подпрограмме, автоматически отражается на всех её вызовах, в то время как при дублировании каждое изменение необходимо вносить в каждое вхождение изменяемого кода.
  • Даже в тех случаях, когда в подпрограмму выделяется однократно производимый набор действий, это оправдано, так как позволяет сократить размеры целостных блоков кода, составляющих программу, то есть сделать программу более понятной и обозримой.

Механизм подпрограмм, их описание и вызов

В простейшем случае (в ассемблерах) подпрограмма представляет собой последовательность команд (операторов), отдельную от основной части программы и имеющую в конце специальную команду выхода из подпрограммы. Обычно подпрограмма также имеет имя, по которому её можно вызвать, хотя ряд языков программирования допускает использование и неименованных подпрограмм. В языках высокого уровня описание подпрограммы обычно состоит по меньшей мере из двух частей: заголовка и тела. Заголовок подпрограммы описывает её имя и, возможно, параметры, то есть содержит информацию, необходимую для вызова подпрограммы. Тело — набор операторов, который будет выполнен всякий раз, когда подпрограмма будет вызвана.

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

В следующем примере на языке Паскаль подпрограмма subprog вызывается из основной программы трижды:

  program SubProgExample;
    // Описание подпрограммы subprog
    procedure subprog; // Заголовок, включающий имя подпрограммы
    begin // начало тела подпрограммы
      WriteLn('Bye');
    end; // конец тела подпрограммы
  begin
    WriteLn('Hello');
    subprog; // 1-й вызов
    subprog; // 2-й вызов
    subprog; // 3-й вызов
  end.

Результатом выполнения такой программы станет вывод строки «Hello» и трёх строк «Bye».

Для сохранения и восстановления контекста выполнения вызывающей процедуры, с целью исключения побочных эффектов, связанных с возможным нежелательным изменением используемых машинных регистров, компилятор формирует для каждой процедуры специальные последовательности команд, называемые прологом и эпилогом процедуры.

Некоторые языки программирования (например, Паскаль, Ада, Модула-2) допускают описание вложенных подпрограмм, то есть помещение подпрограмм внутрь других подпрограмм. Такие вложенные подпрограммы могут использоваться только в той подпрограмме, в которой они описаны. В иных случаях (например, в языке Си) вложение подпрограмм не допускается. Никаких принципиальных преимуществ вложение подпрограмм не даёт, но может быть удобно для более логичной структуризации программы (если какая-то подпрограмма используется только в некоторой другой подпрограмме, логично поместить первую во вторую).

Параметры подпрограмм

Назначение параметров

Подпрограммы часто используются для многократного выполнения стереотипных действий над различными данными. Подпрограмма обычно имеет доступ к объектам данных, описанным в основной программе (по крайней мере, к некоторым из них), поэтому для того, чтобы передать в подпрограмму обрабатываемые данные, их достаточно присвоить, например, глобальным переменным. Но такой путь не особенно удобен и чреват ошибками.

Для обеспечения контролируемой передачи параметров в подпрограмму и возврата результатов из неё используется механизм параметров. Параметры описываются при описании подпрограммы (в её заголовке) и могут использоваться внутри процедуры аналогично переменным, описанным в ней. При вызове процедуры значения каждого из параметров указываются в команде вызова (обычно после имени вызываемой подпрограммы).

  program SubProgExample2;
    // Описание подпрограммы subprog
    procedure subprog(Line: String); // Заголовок, включающий имя подпрограммы
    begin // начало тела подпрограммы
      WriteLn(Line);
    end; // конец тела подпрограммы
  begin
    WriteLn('Hello');
    subprog('Good bye,'); // 1-й вызов
    subprog('my love,');  // 2-й вызов
    subprog('good bye!'); // 3-й вызов
  end.

В приведённом примере параметр Line подпрограммы subprog в каждом вызове получает различное значение, благодаря чему выводятся не одинаковые строки, а разные.

Формальные и фактические параметры

Чтобы отличать параметры подпрограммы, описанные в её заголовке и теле, от параметров, указываемых при вызове подпрограммы, используются формальные и фактические параметры. Формальные параметры указываются при объявлении или определении подпрограммы, а фактические — непосредственно при её вызове. Так, в последнем примере параметр Line в заголовке и теле подпрограммы subprog — это формальный параметр, а строка 'Good bye' , использованная в первом вызове этой подпрограммы — фактический параметр. При вызове подпрограммы фактические параметры, указанные в команде вызова, становятся значениями соответствующих формальных параметров, чем и обеспечивается передача данных в подпрограмму.

Способ передачи параметров в подпрограмму

Существует несколько способов передачи параметров в подпрограмму.

  • Передача параметров по значению. Формальному параметру присваивается значение фактического параметра. В этом случае формальный параметр будет содержать копию значения, имеющегося в фактическом, и никакое воздействие, производимое внутри подпрограммы на формальные параметры, не отражается на параметрах фактических. Так, если в качестве фактического параметра будет использована переменная, и внутри подпрограммы значение соответствующего формального параметра будет изменено, то фактический параметр останется без изменений.
int func1(int x)

{ x=x+1; return x;

}
  • Передача параметров по ссылке. В формальный параметр может быть помещён сам фактический параметр (обычно это реализуется путём помещения в формальный параметр ссылки на фактический). При этом любое изменение формального параметра в подпрограмме отразится на фактическом параметре — оба параметра во время вызова подпрограммы суть одно и то же. Параметры, передаваемые по ссылке, дают возможность не только передавать параметры внутрь подпрограммы, но и возвращать вычисленные значения в точку вызова. Для этого параметру внутри подпрограммы просто присваивается нужное значение, и после возврата из подпрограммы переменная, использованная в качестве фактического параметра, получает это значение.
void func2(int &x)

{ x=x+1;

}
  • Передача параметров по имени. В формальный параметр может быть помещено произвольное выражение. При этом вычисление этого выражения произойдёт внутри подпрограммы в тот момент, когда потребуется его значение. Если это значение фигурирует несколько раз, то и вычисляться оно будет тоже несколько раз. Параметры, передаваемые по имени, дают возможность писать довольно универсальные подпрограммы. Такой способ передачи параметров используется, к примеру в языках Алгол или Алгол 68.
  • Передача параметров через стек. Это фактически разновидность передачи параметра по значению «с ручным приводом», в данном случае отсутствует понятие формальных и фактических параметров. Все параметры лежат на стеке, причём их типы, количество и порядок не контролируются компилятором. Данный подход реализован в языке Форт.

Язык программирования может предоставлять возможность передавать параметры в подпрограммы либо только по значению, либо по значению и по ссылке, либо по имени и значению. В последних двух случаях для различения способов передачи параметра используются отдельные синтаксическая конструкции (в Паскале это ключевое слово var при описании параметра). В действительности, если язык содержит понятие ссылки (указателя), то можно обойтись и без передачи параметра по ссылке (её всегда можно смоделировать, описав параметр типа «ссылка»), но эта возможность удобна, так как позволяет работать с формальным параметром-ссылкой без разыменования, а также повышает надёжность и безопасность программы.

На параметры, передаваемые по ссылке, накладываются естественные ограничения: фактический параметр, подставляемый на место такого параметра при вызове, обязан быть переменной (то есть иметь адрес), а в языках со строгой типизацией — ещё и иметь в точности такой же тип данных.

Виды подпрограмм

В языках программирования высокого уровня используется два типа подпрограмм: процедуры и функции.

  • Функция — это подпрограмма специального вида, которая, кроме получения параметров, выполнения действий и передачи результатов работы через параметры имеет ещё одну особенность— она всегда должна возвращать результат. Вызов функции является, с точки зрения языка программирования, выражением, он может использоваться в других выражениях или в качестве правой части присваивания.
  • Процедура — это независимая именованная часть программы, которую после однократного описания можно многократно вызвать по имени из последующих частей программы для выполнения определенных действий.

Подпрограммы, входящие в состав классов в объектных языках программирования, обычно называются методами. Этим термином называют любые подпрограммы-члены класса, как функции, так и процедуры; когда требуется уточнение, говорят о методах-процедурах или методах-функциях.

См. также


К:Википедия:Статьи без источников (тип: не указан)

Напишите отзыв о статье "Подпрограмма"

Отрывок, характеризующий Подпрограмма

Первое время своего знакомства с Сперанским князь Андрей питал к нему страстное чувство восхищения, похожее на то, которое он когда то испытывал к Бонапарте. То обстоятельство, что Сперанский был сын священника, которого можно было глупым людям, как это и делали многие, пошло презирать в качестве кутейника и поповича, заставляло князя Андрея особенно бережно обходиться с своим чувством к Сперанскому, и бессознательно усиливать его в самом себе.
В тот первый вечер, который Болконский провел у него, разговорившись о комиссии составления законов, Сперанский с иронией рассказывал князю Андрею о том, что комиссия законов существует 150 лет, стоит миллионы и ничего не сделала, что Розенкампф наклеил ярлычки на все статьи сравнительного законодательства. – И вот и всё, за что государство заплатило миллионы! – сказал он.
– Мы хотим дать новую судебную власть Сенату, а у нас нет законов. Поэтому то таким людям, как вы, князь, грех не служить теперь.
Князь Андрей сказал, что для этого нужно юридическое образование, которого он не имеет.
– Да его никто не имеет, так что же вы хотите? Это circulus viciosus, [заколдованный круг,] из которого надо выйти усилием.

Через неделю князь Андрей был членом комиссии составления воинского устава, и, чего он никак не ожидал, начальником отделения комиссии составления вагонов. По просьбе Сперанского он взял первую часть составляемого гражданского уложения и, с помощью Code Napoleon и Justiniani, [Кодекса Наполеона и Юстиниана,] работал над составлением отдела: Права лиц.


Года два тому назад, в 1808 году, вернувшись в Петербург из своей поездки по имениям, Пьер невольно стал во главе петербургского масонства. Он устроивал столовые и надгробные ложи, вербовал новых членов, заботился о соединении различных лож и о приобретении подлинных актов. Он давал свои деньги на устройство храмин и пополнял, на сколько мог, сборы милостыни, на которые большинство членов были скупы и неаккуратны. Он почти один на свои средства поддерживал дом бедных, устроенный орденом в Петербурге. Жизнь его между тем шла по прежнему, с теми же увлечениями и распущенностью. Он любил хорошо пообедать и выпить, и, хотя и считал это безнравственным и унизительным, не мог воздержаться от увеселений холостых обществ, в которых он участвовал.
В чаду своих занятий и увлечений Пьер однако, по прошествии года, начал чувствовать, как та почва масонства, на которой он стоял, тем более уходила из под его ног, чем тверже он старался стать на ней. Вместе с тем он чувствовал, что чем глубже уходила под его ногами почва, на которой он стоял, тем невольнее он был связан с ней. Когда он приступил к масонству, он испытывал чувство человека, доверчиво становящего ногу на ровную поверхность болота. Поставив ногу, он провалился. Чтобы вполне увериться в твердости почвы, на которой он стоял, он поставил другую ногу и провалился еще больше, завяз и уже невольно ходил по колено в болоте.
Иосифа Алексеевича не было в Петербурге. (Он в последнее время отстранился от дел петербургских лож и безвыездно жил в Москве.) Все братья, члены лож, были Пьеру знакомые в жизни люди и ему трудно было видеть в них только братьев по каменьщичеству, а не князя Б., не Ивана Васильевича Д., которых он знал в жизни большею частию как слабых и ничтожных людей. Из под масонских фартуков и знаков он видел на них мундиры и кресты, которых они добивались в жизни. Часто, собирая милостыню и сочтя 20–30 рублей, записанных на приход, и большею частию в долг с десяти членов, из которых половина были так же богаты, как и он, Пьер вспоминал масонскую клятву о том, что каждый брат обещает отдать всё свое имущество для ближнего; и в душе его поднимались сомнения, на которых он старался не останавливаться.
Всех братьев, которых он знал, он подразделял на четыре разряда. К первому разряду он причислял братьев, не принимающих деятельного участия ни в делах лож, ни в делах человеческих, но занятых исключительно таинствами науки ордена, занятых вопросами о тройственном наименовании Бога, или о трех началах вещей, сере, меркурии и соли, или о значении квадрата и всех фигур храма Соломонова. Пьер уважал этот разряд братьев масонов, к которому принадлежали преимущественно старые братья, и сам Иосиф Алексеевич, по мнению Пьера, но не разделял их интересов. Сердце его не лежало к мистической стороне масонства.
Ко второму разряду Пьер причислял себя и себе подобных братьев, ищущих, колеблющихся, не нашедших еще в масонстве прямого и понятного пути, но надеющихся найти его.
К третьему разряду он причислял братьев (их было самое большое число), не видящих в масонстве ничего, кроме внешней формы и обрядности и дорожащих строгим исполнением этой внешней формы, не заботясь о ее содержании и значении. Таковы были Виларский и даже великий мастер главной ложи.
К четвертому разряду, наконец, причислялось тоже большое количество братьев, в особенности в последнее время вступивших в братство. Это были люди, по наблюдениям Пьера, ни во что не верующие, ничего не желающие, и поступавшие в масонство только для сближения с молодыми богатыми и сильными по связям и знатности братьями, которых весьма много было в ложе.
Пьер начинал чувствовать себя неудовлетворенным своей деятельностью. Масонство, по крайней мере то масонство, которое он знал здесь, казалось ему иногда, основано было на одной внешности. Он и не думал сомневаться в самом масонстве, но подозревал, что русское масонство пошло по ложному пути и отклонилось от своего источника. И потому в конце года Пьер поехал за границу для посвящения себя в высшие тайны ордена.

Летом еще в 1809 году, Пьер вернулся в Петербург. По переписке наших масонов с заграничными было известно, что Безухий успел за границей получить доверие многих высокопоставленных лиц, проник многие тайны, был возведен в высшую степень и везет с собою многое для общего блага каменьщического дела в России. Петербургские масоны все приехали к нему, заискивая в нем, и всем показалось, что он что то скрывает и готовит.
Назначено было торжественное заседание ложи 2 го градуса, в которой Пьер обещал сообщить то, что он имеет передать петербургским братьям от высших руководителей ордена. Заседание было полно. После обыкновенных обрядов Пьер встал и начал свою речь.
– Любезные братья, – начал он, краснея и запинаясь и держа в руке написанную речь. – Недостаточно блюсти в тиши ложи наши таинства – нужно действовать… действовать. Мы находимся в усыплении, а нам нужно действовать. – Пьер взял свою тетрадь и начал читать.
«Для распространения чистой истины и доставления торжества добродетели, читал он, должны мы очистить людей от предрассудков, распространить правила, сообразные с духом времени, принять на себя воспитание юношества, соединиться неразрывными узами с умнейшими людьми, смело и вместе благоразумно преодолевать суеверие, неверие и глупость, образовать из преданных нам людей, связанных между собою единством цели и имеющих власть и силу.
«Для достижения сей цели должно доставить добродетели перевес над пороком, должно стараться, чтобы честный человек обретал еще в сем мире вечную награду за свои добродетели. Но в сих великих намерениях препятствуют нам весьма много – нынешние политические учреждения. Что же делать при таковом положении вещей? Благоприятствовать ли революциям, всё ниспровергнуть, изгнать силу силой?… Нет, мы весьма далеки от того. Всякая насильственная реформа достойна порицания, потому что ни мало не исправит зла, пока люди остаются таковы, каковы они есть, и потому что мудрость не имеет нужды в насилии.
«Весь план ордена должен быть основан на том, чтоб образовать людей твердых, добродетельных и связанных единством убеждения, убеждения, состоящего в том, чтобы везде и всеми силами преследовать порок и глупость и покровительствовать таланты и добродетель: извлекать из праха людей достойных, присоединяя их к нашему братству. Тогда только орден наш будет иметь власть – нечувствительно вязать руки покровителям беспорядка и управлять ими так, чтоб они того не примечали. Одним словом, надобно учредить всеобщий владычествующий образ правления, который распространялся бы над целым светом, не разрушая гражданских уз, и при коем все прочие правления могли бы продолжаться обыкновенным своим порядком и делать всё, кроме того только, что препятствует великой цели нашего ордена, то есть доставлению добродетели торжества над пороком. Сию цель предполагало само христианство. Оно учило людей быть мудрыми и добрыми, и для собственной своей выгоды следовать примеру и наставлениям лучших и мудрейших человеков.
«Тогда, когда всё погружено было во мраке, достаточно было, конечно, одного проповедания: новость истины придавала ей особенную силу, но ныне потребны для нас гораздо сильнейшие средства. Теперь нужно, чтобы человек, управляемый своими чувствами, находил в добродетели чувственные прелести. Нельзя искоренить страстей; должно только стараться направить их к благородной цели, и потому надобно, чтобы каждый мог удовлетворять своим страстям в пределах добродетели, и чтобы наш орден доставлял к тому средства.
«Как скоро будет у нас некоторое число достойных людей в каждом государстве, каждый из них образует опять двух других, и все они тесно между собой соединятся – тогда всё будет возможно для ордена, который втайне успел уже сделать многое ко благу человечества».
Речь эта произвела не только сильное впечатление, но и волнение в ложе. Большинство же братьев, видевшее в этой речи опасные замыслы иллюминатства, с удивившею Пьера холодностью приняло его речь. Великий мастер стал возражать Пьеру. Пьер с большим и большим жаром стал развивать свои мысли. Давно не было столь бурного заседания. Составились партии: одни обвиняли Пьера, осуждая его в иллюминатстве; другие поддерживали его. Пьера в первый раз поразило на этом собрании то бесконечное разнообразие умов человеческих, которое делает то, что никакая истина одинаково не представляется двум людям. Даже те из членов, которые казалось были на его стороне, понимали его по своему, с ограничениями, изменениями, на которые он не мог согласиться, так как главная потребность Пьера состояла именно в том, чтобы передать свою мысль другому точно так, как он сам понимал ее.