формальный и фактический параметр
Формальные и фактические параметры
Рассмотрим более подробно вопросы взаимодействия формальных и фактических параметров.
Определения формальных и фактических параметров являются исключительно важными для понимания механизма их взаимодействия в подпрограммах. Поэтому на этом вопросе следует остановиться подробнее.
Формальные параметры подпрограммы указывают, с какими параметрами следует обращаться к этой подпрограмме (количество параметров, их последовательность, типы). Они задаются в заголовке подпрограммы в виде списка формальных параметров, разбитого на группы, разделенные точками с запятыми. В группу формальных параметров включаются однотипные параметры одной категории.
Все формальные параметры можно разбить на четыре категории:
— параметры-значения (эти параметры подпрограмма может изменить в основной подпрограмме);
— параметры-переменные (эти параметры подпрограмма может изменить в основной программе);
— параметры-константы (только в версии 7.0);
— параметры-процедуры и параметры-функции (т.е. процедурного типа).
Для каждого формального параметра следует указать имя и, как правило, тип, а в случае параметра-переменной или параметра-константы — категорию. Имена параметров могут быть любыми, в том числе и совпадать с именами объектов программы. Необходимо лишь помнить, что в этом случае параметр основной программы с таким именем становится недоступным для непосредственного использования подпрограммой. Тип формального параметра может быть практически любым, однако в заголовке подпрограммы нельзя вводить новый тип.
Например, нельзя писать
Function SUMM (A: array[1..100] of Real): Real;
Чтобы правильно записать этот заголовок, следует в основной программе ввести тип-массив, а затем использовать его в заголовке:
Type aArr = array[1..100] of real;
Function SUMM (A: aArr): Real;
При обращении к подпрограмме формальные параметры заменяются на соответствующие фактическиевызывающей программы или подпрограммы.
Параметры-значения передаются основной программой в подпрограмму через стек (специальный канал передачи данных) в виде их копий и, следовательно, собственный параметр программы подпрограммой измениться не может.
Параметр-значение указывается в заголовке подпрограммы своим именем и через двоеточие — типом. Тип параметра-значения может быть любым, за исключением файлового.
Если параметров-значений одного типа несколько, их можно объединить в одну группу, перечислив их имена через запятую, а затем уже указать общий тип. Как было отмечено выше, отдельные группы параметров отделяются друг от друга точкой с запятой.
Procedure MIN_MAX(Max,Min: Real; n: Word);
Function Tabulir(X,Y: Integer): Real;
В качестве фактического параметра на месте параметра-значения при вызове подпрограммы может выступать любое выражение совместимого для присваивания типа, не содержащее файловую компоненту, например:
Пример 2.6.Использовать функцию для вычисления максимального элемента в массиве.
Определим в основной программе тип-массив.
aArr = Array[1..] of Integer;
Var Massiv: aArr; Maxim: Integer;
Функция в этом случае может иметь следующий вид.
Function Max(Mas: aArr; N: Byte): Integer;
Var Ma : Integer; i : Byte;
If MaMas[i] then Ma := Mas[i];
Пусть надо определить максимальное число из первых 35 чисел массива. Это можно сделать с помощью оператора, использующего обращение к функции: Maxim := Max(Massiv,35);
Примечание. Данная программа может работать только с массивами типа аАrr. Для массивов другого типа надо создавать другую аналогичную подпрограмму. Данная программа создает в стеке копию исходного массива, поэтому она работает медленно.
Параметр-переменная указывается в заголовке подпрограммы аналогично параметру-значению, но только перед именем параметра записывается зарезервированное слово VAR. Действие слова VAR распространяется до ближайшей точки с запятой, т.е. в пределах одной группы.
Пример 2.8. Procedure MaxMin(A: аАrr; Var Max, Min: Real; N: Word);
Здесь Max, Min- параметры-переменные, а переменные А и N — параметры-значения.
Тип параметров-переменных может быть любым, включая и файловый. При вызове подпрограммы на месте параметра-переменной в качестве фактического параметра должна использоваться переменная идентичного типа. Так, если формальный параметр имеет тип, определенный следующим образом:
Type аАrr = array [1.. 100] of Integer;
то и фактический параметр должен быть переменной или типизированной константой типа аАrr.
Использовать функцию для вычисления максимального элемента в массиве.
В основной программе определяется тип-массив.
Type аАrr = Array [1.. 50] of Integer;
Var Massiv: аАrr; Maxim: Integer;
Функция в этом случае может иметь вид:
Function Max(Var Mas: аАгг; N: Byte): Integer;
Var Ma : Integer; i : Byte;
If MaMas[i] then Ma := Mas[i];
Пусть надо определить максимальное число из первых 35 чисел массива Это можно сделать с помощью оператора:
Примечание. Эта программа лучше предыдущей тем, что в данном случае в стеке не создается копия исходного массива, что улучшает быстродействие и экономит память. Однако при такой передаче параметра возможно его нежелательное изменение (этот вариант передачи параметра допустим только в таких небольших подпрограммах, как в данном случае, когда программист может проконтролировать несанкционированное изменение параметра). Недостатком этой программы, как и ранее описанной, является то, что она может работать только с одним типом массива.
Часто в качестве параметра в подпрограмму следует передать ту или иную переменную, но изменять ее подпрограмма не должна. В этом случае нежелательно передавать этот параметр как параметр-переменную. Можно его передать как параметр-значение, однако если эта переменная имеет больший размер (массив, запись и т.д.), то копия этого параметра займет большую часть стека и даже может его переполнить. Это приводит также к уменьшению быстродействия программы. В этой ситуации параметр лучше передать как параметр-константу. Такой параметр, если он структурированного типа, передается своим адресом, но предусматривается защита от его изменения. Использовать параметр-константу можно только в версии Турбо Паскаля 7.0.
Параметр-константа указывается в заголовке подпрограммы аналогично параметру-значению, но перед именем параметра записывается зарезервированное слово Const. Действие слова Const распространяется до ближайшей точки с запятой, т.е. в пределах одной группы.
Пример 2.10.Function NewString(Const S: String): String;
Тип параметра-значения может быть любым, за исключением файлового. При вызове подпрограммы на месте параметра-переменной в качестве фактического параметра можно использовать любое выражение совместимого для присваивания типа, не содержащего файловую компоненту.
Параметр-константу нельзя передавать в другую подпрограмму в качестве фактического параметра.
Функция вычисления максимального элемента в массиве, и в качестве первого параметра – параметр-константа.
Function Max(Const Mas: аАrr; N: Byte): Integer;
Var Ma : Integer; i : Byte;
If MaMas[i] then Ma := Mas[i];
Параметры без типа
В Турбо Паскале можно использовать параметры-переменные и параметры-константы без указания типа. В этом случае фактический параметр может быть переменной любого типа,а ответственность за правильное использование того или иного параметра возлагается на программиста.
Пример 2.12.Function Tqual(Var Param1, Param2; Len: Word):Boolean;
Здесь Param1, Param2 — параметры-переменные без типа (вместо них можно использовать, например, любые переменные простого типа, типа-массив, типа-запись и т.д.); Len — параметр-значение.
Следует иметь в виду, что параметр “без типа” внутри подпрограммы типа не имеет и его перед использованием следует преобразовать к конкретному типу, применяя идентификатор соответствующего типа так, как ранее указывалось, при этом полученный результат может быть любого размера.
Пример 2.13.Функция вычисления максимального элемента в массиве. При этом в качестве первого параметра используется параметр-переменная без типа:
Function Max(Var Masr; N: Byte): Integer;
Type aArray = array[Maxint] of Integer;
Var Ма : Integer; i : Byte;
Begin Ма := aArray(Mas)[1];
If МаaArray(Mas)[i] then Ма := aArray(Mas)[i];
В этом случае в качестве первого передаваемого параметра можно использовать любой массив (и не только массив), так что подпрограмма становится более универсальной. Тем не менее здесь необходимо передавать в качестве второго параметра фактический размер информации, что не очень удобно.
Статьи к прочтению:
Ээ в этом случае наши полномочия все окончены
Похожие статьи:
Лабораторная работа №3 Использование подпрограмм в системе MATLAB Цель работы: Знакомство с организацией функций в MATLAB, особенностями их работы….
Существует несколько способов передачи параметров в подпрограмму. § Передача параметров по значению. Формальному параметру присваивается значение…
Функции и процедуры. Рекурсия
Теоретический материал (Паскаль)
Понятие подпрограммы. Процедуры и функции. Стандартные подпрограммы
Подпрограммы решают три важные задачи:
Очень важно понимать, что в подпрограмму может выделяться любой законченный фрагмент программы. В качестве ориентиров просмотрите следующие рекомендации:
Подпрограммы могут быть стандартными, т.е. определенными системой, и собственными, т.е. определенными программистом.
Из набора стандартных процедур и функций по обработке одного типа информации составляются модули. Каждый модуль имеет своё имя (мы уже хорошо знакомы с модулями Crt, Graph). Доступ к процедурам и функциям модуля осуществляется при подключении этого модуля (Uses Crt, Graph).
Задание. Вызовите помощь по функции Cos и рассмотрите предоставленную информацию.
Сначала идет краткое описание подпрограммы (в одну фразу). Далее под словом Declaration (Объявление) следует интерфейсная часть процедуры или функции, которая необходима для определения типов фактических параметров. Далее под словом Target приводятся платформы, на которых может использоваться подпрограмма: Windows, real (реальный режим DOS), protected (защищенный режим DOS). После слова Remarks следуют заметки, содержащие необходимые детали использования. В разделе See Also приведены имена подпрограмм, связанных с данной по смыслу или по совместному применению. Если перемещать курсор по этим именам (они выделяются подсветкой), то, выбрав одно из них (нажав клавишу ), можно получить справку по следующей подпрограмме. Каждая процедура и функция сопровождается примером применения, переключение к которому дает последняя строка справочной информации. Любой текст из Help может быть скопирован в редактируемый файл обычными приемами копирования через буфер. Копирование примеров или заголовков функций может значительно облегчить работу.
Существует другой способ получения сведений о процедурах и функциях. Для этого нужно использовать пункт меню Help/Reserved words (зарезервированные слова) или Help/Standard units (стандартные модули).
Задание. Рассмотрите список процедур и функций, выберите какие-либо из них и ознакомьтесь со справочной информацией.
В стандартных модулях содержится большое количество подпрограмм, но невозможно создать модуль, который бы содержал все нужные программисту подпрограммы. Поэтому большую роль играют собственные подпрограммы, которые создает программист для решения конкретной задачи.
Существует два способа объединения программ и подпрограмм пользователя:
Первый способ применяется тогда, когда программа в целом не очень большая, а ее подпрограммы, скорее всего, не будут использоваться в других программах.
Структура текста подпрограммы соответствует структуре текста основной программы за двумя исключениями:
Вызов подпрограммы происходит при каждом употреблении ее имени в основной (или вызывающей) программе. При вызове подпрограммы выполнение основной программы приостанавливается, и управление передается в подпрограмму, где выполняются команды, заданные в ней. Подпрограмма завершается, если выполнены все ее операторы до завершающего слова End или по специальной команде выхода из подпрограммы Exit. По окончании работы подпрограммы управление возвращается основной программе, а именно, первой команде, следующей за обращением к этой подпрограмме.
Например, вызов функции
вернет в основную программу значение наименьшего из двух чисел и это значение будет присвоено переменной M.
Все переменные, которые использует подпрограмма, могут быть либо глобальными, либо локальными.
Определение. Глобальными называются переменные, объявленные в основной программе и доступные как программе, так и всем ее подпрограммам.
Определение. Локальными называются переменные, объявленные внутри подпрограммы и доступные только ей самой.
Обмен информацией между основной программой и подпрограммой может осуществляться только с помощью глобальных переменных и с помощью параметров подпрограммы.
Подпрограмма может использовать любые глобальные переменные кроме тех, которые имеют те же имена, что и ее локальные переменные. Если в подпрограмме описана локальная переменная, имя которой совпадает с именем некоторой глобальной переменной, то данная глобальная переменная становится недоступной в этой подпрограмме, и при указании идентификатора переменной произойдет обращение к локальной переменой подпрограммы, а не одноименной глобальной переменной. Память для локальных (т.е. описанных в подпрограмме) переменных выделяется на время исполнения данной подпрограммы в специальной области, называемой стеком. При завершении работы подпрограммы память освобождается, поэтому все внутренние результаты работы подпрограммы не сохраняются от одного обращения к другому.
Если говорить о плюсах использования подпрограмм, то можно назвать следующие:
В языке Паскаль выделяют два вида подпрограмм: процедуры (Procedure) и функции (Function). Любая программа может содержать несколько процедур и функций. Структура любой подпрограммы аналогична структуре всей программы.
Подпрограмма должна быть описана до того, как будет использована в программе или другой подпрограмме.
Процедуры и функции объявляются в разделе описания вслед за разделом переменных.
Общая структура программы выглядит так:
Выполнение программы начинается с операторов основной программы. При необходимости вызывается подпрограмма, и начинают действовать её операторы. Затем управление возвращается в основную программу, которая и продолжает выполняться.
Подпрограмма вызывается по своему имени с указанием необходимых параметров.
На этом занятии рассмотрим примеры организации наиболее простого вызова подпрограмм.
Задание. Рассмотрите решение предложенных задач, наберите программы на компьютере, проверьте их работоспособность, внесите свои изменения и дополните своими комментариями.
Задача 1. Написать программу, состоящую из трех подпрограмм и основной программы. Подпрограммы должны организовывать ввод чисел, вычисление их суммы и вывод результата.
Задача 2. Найти среднее арифметическое двух чисел.
Фактические параметры. Связывание фактических и формальных параметров.
Список фактических параметров задается перечислением через запятую фактических данных, над которыми функция должна выполнять действия при данном вызове. При обращении к функции между списком формальных и списком фактических параметров устанавливается соответствие: по взаимному расположению параметров в списках (первому формальному параметру соответствует первый фактический параметр и т. д.), количеству, типу и способу связывания.
Связь между формальными и фактическими параметрами может устанавливаться двумя способами:
– связь по значению – значение фактического параметра присваивается формальному. Действия в подпрограмме выполняются над формальной переменной, получившей значение фактического пара-метра;
– связь по адресу (ссылке) – фактический параметр заменяет в теле подпрограммы формальный, и подпрограмма получает доступ к фактическому параметру. Если говорить более точно, то формальному параметру присваивается адрес (ссылка) фактического параметра. Значение такого формального параметра при его использовании в операциях рассматривается как адрес того объекта, над которым надо выполнить эту операцию. Такой способ используется как для передачи входных данных, так и прежде всего для выходных данных (результатов).
В Си связь между формальными и фактическими параметрами устанавливается по значению. Фактический параметр в этом случае – выражение того же типа, что и соответствующий ему формальный. В момент вызова функции вычисляется значение фактического параметра и присваивается формальному параметру. Такой способ позволяет передать в подпрограмму значения входных данных. Изменение формального параметра, получившего значение фактического, не приводит к изменению фактического параметра.
Если через список формальных параметров должен передаваться результат функции, то формальный параметр должен быть типа указатель, а соответствующий ему фактический параметр – это выражение, значение которого есть адрес переменной результата.
Понятие глобального (внешнего) объекта
Глобальные объекты – это объекты, описанные вне всех функций (сама функция тоже является глобальным объектом). Сфера действия глобальных имен – модуль (файл) с текстом программы от точки описания имени до конца файла. Внутри каждой функции, входящей в модуль, они имеют один и тот же смысл. Повторное определение глобального объекта в теле функции изменяет его видимость. Внутри функции сфера действия глобальных имен сохраняется до точки их повторного описания. После выхода из функции (или внутреннего блока, содержащего повторное описание глобального имени) восстанавливается видимость глобальных объектов, переопределенных внутри функции. Если глобальный объект определен позже своего первого использования, то он должен быть описан в той функции, где он используется с атрибутом extern.
Модули
Программный продукт построенный по принципам модульного программирования обладает как называемой архитектурой то есть он состоит из взаимосвязанных между собой частей. И такую часть программного продукта принято называть модуль.
Модуль– самостоятельная часть программы имеющая определенное назначение и обеспечивающая заданные функции обработки автономно от других программных модулей. Каждый модуль характеризуется своим назначениеми интерфейсом.
Назначение– определяется неформально как правило на псевдо языке.
Интерфейс – складывается из спецификаций объектов двух типов
1.Тип – Экспорт модуля– те объекты (константы, переменные, функции) которые реализуются данным модулем и могут быть использованы вне этих модулей.
2.Тип – Импорт модуля – те объекты которые используются в данном модуле.
Модуль как строительный материал программной системы должен быть таким, чтобы его назначение и интерфейс соответствовали возможности его использования в других модулях программы.
Кроме импортированных и экспортированных объектов могут быть и внутренние объекты. Они скрыты от других модулей.
Каждый модуль должен компилироваться отдельно от других модулей программной системы.
Модуль должен скрывать (инкапсулировать) реализацию экспортируемых объектов. Это необходимо для того чтобы при модификации не пострадали другие модули.
При создании программного продукта выделяются многократно используемые части программы, проводится их типизация и унификация. На основе этого составляются модули.
Нет жестких правил для определения модуля.
Принято различать следующие модули:
1.Головной – модуль управляющий запуском программного продукта.
2.Управляющий – обеспечивает вызов других модулей как правило в программе он один но допускается и другое количество.
3.Рабочий – модуль выполняющий функции обработки. Таких модулей может быть множество.
4.Сервисный– модуль обеспечивает обслуживание функции.
Взаимодействие объектов в программе :
В программе имеющей модульно – блочную структуру возникает проблема взаимодействия объектов определенных в разных областях программы. Эта проблема решается на основе принципа локализации объектов.
Местом или областью локализации может быть:
2.Функция(то есть ее определение)
1.Область действия– часть программы в которой существует связь между некоторым именем объекта. По средствам имени обеспечивается обращение к объекту. Область действия имени начинается с точки где определен объект и заканчивается концом той области в которой он локализован (конец блока, модуля, файла).
2.Пространство имен– расширяет область действия имени – область в пределах которой имя должно быть уникальным. Имена переменных, имена функций, имена типов введенных пользователем должны быть уникальными в пределах их области действия. Если переменная определена в блоке, то ее имя уникально в блоке и т.д. (смотри структуры).
3.Видимость объекта – этот атрибут характеризует взаимодействие объектов с одинаковыми именами но с разной локализацией. Если в области внутренней по отношению к другой области определен объект с таким же именем как и объект вне внутренней области то во внутренней области виден объект определенный в ней самой (данное правило однозначно позволяет использовать под одним именем только один объект).
Кроме атрибутов определены следующие качества:
Продолжительность существования объекта– период времени в течении которого любому имени соответствует конкретный объект расположенный в области памяти. продолжительность может быть:
1.Локальной –локальную продолжительность имеют локальные объекты. Такие объекты создаются при входе в блок и не доступны при выходе из него.
2.Статической – статическая продолжительность определяет период существования объекта начиная с его определения и заканчивая концом программы то есть перестает существовать когда программа завершает работу (все функции имеют статическую продолжительность). Локальному объекту может быть приписана статическая продолжительность существования только явно. Память статическим объектам выделяется в начале выполнения программы когда эти объекты определяются и до конца существования программы.
Объекты с динамической продолжительностью существования создаются и уничтожаются в процессе выполнения программы по явным запросам о создании и удалении объекта.
Этот атрибут возник для программ с модульной структурой.
Определение соответствующего имени объекта (переменной, константе, функции) в программе состоящей из нескольких модулей. Внутри модуля способ связывания – внутренний.
Выделение памяти и связь с именем происходит на этапе трансляции. Для объектов определенных в программе с модульной структурой может быть определено внешнее связывание – это связывание определяется в тех случаях когда объект определенный в одном модуле должен быть использован в другом. Для функций по умолчанию установлено внешнее связывание по этому функция определенная в одном модуле может быть определена в другом. Для переменных внешнее связывание задается только явно. Для этого используется еще один атрибут называемый класс памяти – определяет размещение объекта в ОЗУ продолжительность его существования и его способ связывания.
1.Автоматическая память (auto) – этот класс выделяется объектам блока, выделяется либо в стеке либо в регистре. Объекты этого класса имеют локальную продолжительность существования.
2.Статическая память (static) –этот класс приписан объектам явно и задает статическую продолжительность существования, память выделяется в сегменте данных.
3.Внешняя память (extern) –задает статическую продолжительность существования внешний способ связывания память выделяется в сегменте программы данных. Функции по умолчанию приписываются к классу extern.
Для переменных класс приписывается явно. При определении объекта ему приписывается не только тип но и класс памяти, продолжительность существования, тип связывания, область действия имени и т.д.
Явно задается только класс памяти.
Общее определение обьекта:
[класс памяти][модификатор] тип имя [инициализатор] ([] – говорит о том что то что внутри может быть опущено).
При определении объекта переменной или константы класс extern не используется. Этот класс используется при описании объектов. По определению ему задается имя, и другие атрибуты, тип, выделение памяти.
Описание – информация для транслятора об объекте.
Описание: [класс памяти][модификатор] тип имя, но без инициализатора так как это информация только для транслятора.
Рекурсия
1. обрабатываемые данные имеют рекурсивную природу
2. нет для задачи итеративного способа решения – в этом случае применяют метод полного или частичного перебора возможных вариантов решения задачи.
Для реализации рекурсии в я.п. предлагается механизм, состоящий в возможности обращения подпрограммы к самой себе. Когда происходит очередной вызов подпрограммы, создаются новые экземпляры (поколения) формальных параметров и внутренних (локальных) переменных. При этом определено правило доступности экземпляров переменных – на некотором уровне рекурсии или же вызове подпрограмм доступны только те экземпляры переменных, которые соответствуют этому вызову. Для реализации правила доступности переменных используется стековая память – область памяти с определенным правилом обращения к элементам. Это правило состоит в следующем – в стеке доступен тот элемент, который был помещен в него последним. Непосредственная рекурсия – когда подпрограмма вызывает сама себя. Косвенная рекурсия – существует функция А, которая вызывает функцию В, которая, в свою очередь, вызывает функцию А. В стековой памяти хранятся не только значения подпрограмм, но и для каждого уровня рекурсии хранится текущее состояние подпрограмм. Для того, чтобы избежать при рекурсивном решении повторных вычислений одних и тех же величин необходимо передавать результаты промежуточных вычислений с одного уровня рекурсии на другой. Нет общего правила выполнения для каждой задачи, в каждой задаче это решается непосредственно для этой задачи, но с использованием дополнительных переменных. Реализация решения может проходить в одной из трех форм описания рекурсивного решения:
1. говорит о том, что реализация решения осуществляется на этапе рекурсивного разворачивания (спуска)
2. задача решается на этапе сворачивания рекурсий
Вызов подпрограммы; s>
3. когда часть задачи решается на этапе разворачивания, а часть – на этапе сворачивания
Рекурсивное решение задачи является важным и мощным методом, который характеризует определенное свойство абстрактного мышления, при котором избавляемся от последовательного (итеративного) способа решения задачи, но выявляем различные уровни решения задачи – частные случаи. Рекурсивное описание решения задачи всегда короче и нагляднее итеративного, но реализация рекурсивного решения всегда занимает больше времени, чем итеративное. Кроме того, затрагивается дополнительная память для получения результата и их сохранения на различных уровнях решения задач.
Рекурсивные алгоритмы наиболее пригодны в случаях, когда поставленная задача или используемые данные определены рекурсивно. В тех случаях, когда вычисляемые значения определяются с помощью простых рекуррентных соотношений, гораздо эффективнее применить итеративные методы. Таким образом, определение корня математической функции, возведение в степень и вычисление факториала только иллюстрируют схемы организации рекурсивных функций, но не являются примерами эффективного применения рекурсивного подхода к вычислениям.
Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим.
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰).
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций.