Фактические параметры. Связывание фактических и формальных параметров.

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

Связь между формальными и фактическими параметрами может устанавливаться двумя способами:

– связь по значению – значение фактического параметра присваивается формальному. Действия в подпрограмме выполняются над формальной переменной, получившей значение фактического пара-метра;

– связь по адресу (ссылке) – фактический параметр заменяет в теле подпрограммы формальный, и подпрограмма получает доступ к фактическому параметру. Если говорить более точно, то формальному параметру присваивается адрес (ссылка) фактического параметра. Значение такого формального параметра при его использовании в операциях рассматривается как адрес того объекта, над которым надо выполнить эту операцию. Такой способ используется как для передачи входных данных, так и прежде всего для выходных данных (результатов).

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

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

Понятие глобального (внешнего) объекта

Глобальные объекты – это объекты, описанные вне всех функций (сама функция тоже является глобальным объектом). Сфера действия глобальных имен – модуль (файл) с текстом программы от точки описания имени до конца файла. Внутри каждой функции, входящей в модуль, они имеют один и тот же смысл. Повторное определение глобального объекта в теле функции изменяет его видимость. Внутри функции сфера действия глобальных имен сохраняется до точки их повторного описания. После выхода из функции (или внутреннего блока, содержащего повторное описание глобального имени) восстанавливается видимость глобальных объектов, переопределенных внутри функции. Если глобальный объект определен позже своего первого использования, то он должен быть описан в той функции, где он используется с атрибутом extern.

Модули

Понятие модуля:

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

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

Назначение– определяется неформально как правило на псевдо языке.

Интерфейс – складывается из спецификаций объектов двух типов

1.Тип – Экспорт модуля– те объекты (константы, переменные, функции) которые реализуются данным модулем и могут быть использованы вне этих модулей.

2.Тип – Импорт модуля – те объекты которые используются в данном модуле.

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

Кроме импортированных и экспортированных объектов могут быть и внутренние объекты. Они скрыты от других модулей.

Каждый модуль должен компилироваться отдельно от других модулей программной системы.

Модуль должен скрывать (инкапсулировать) реализацию экспортируемых объектов. Это необходимо для того чтобы при модификации не пострадали другие модули.

При создании программного продукта выделяются многократно используемые части программы, проводится их типизация и унификация. На основе этого составляются модули.

Нет жестких правил для определения модуля.

Принято различать следующие модули:

1.Головной – модуль управляющий запуском программного продукта.

2.Управляющий – обеспечивает вызов других модулей как правило в программе он один но допускается и другое количество.

3.Рабочий – модуль выполняющий функции обработки. Таких модулей может быть множество.

4.Сервисный– модуль обеспечивает обслуживание функции.

Взаимодействие объектов в программе :

В программе имеющей модульно – блочную структуру возникает проблема взаимодействия объектов определенных в разных областях программы. Эта проблема решается на основе принципа локализации объектов.

Местом или областью локализации может быть:

1.Блок

2.Функция(то есть ее определение)

3.Модуль (файл)

4.Протатип функции

Каждый объект существует и доступен только в той области в которой он локализован то есть определен. Объект, определенный в блоке, называется локальным в функции - формальный объект(локальный) в модуле (функция, определение функции, определение констант) называется глобальным объектом. Этот объект характеризуется совокупностью атрибутов объекта:

1.Область действия– часть программы в которой существует связь между некоторым именем объекта. По средствам имени обеспечивается обращение к объекту. Область действия имени начинается с точки где определен объект и заканчивается концом той области в которой он локализован (конец блока, модуля, файла).

2.Пространство имен– расширяет область действия имени – область в пределах которой имя должно быть уникальным. Имена переменных, имена функций, имена типов введенных пользователем должны быть уникальными в пределах их области действия. Если переменная определена в блоке, то ее имя уникально в блоке и т.д. (смотри структуры).

3.Видимость объекта – этот атрибут характеризует взаимодействие объектов с одинаковыми именами но с разной локализацией. Если в области внутренней по отношению к другой области определен объект с таким же именем как и объект вне внутренней области то во внутренней области виден объект определенный в ней самой (данное правило однозначно позволяет использовать под одним именем только один объект).

Кроме атрибутов определены следующие качества:

Продолжительность существования объекта– период времени в течении которого любому имени соответствует конкретный объект расположенный в области памяти. продолжительность может быть:

1.Локальной –локальную продолжительность имеют локальные объекты. Такие объекты создаются при входе в блок и не доступны при выходе из него.

2.Статической – статическая продолжительность определяет период существования объекта начиная с его определения и заканчивая концом программы то есть перестает существовать когда программа завершает работу (все функции имеют статическую продолжительность). Локальному объекту может быть приписана статическая продолжительность существования только явно. Память статическим объектам выделяется в начале выполнения программы когда эти объекты определяются и до конца существования программы.

Объекты с динамической продолжительностью существования создаются и уничтожаются в процессе выполнения программы по явным запросам о создании и удалении объекта.

Способ связывания:

Этот атрибут возник для программ с модульной структурой.

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

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

Классы:

1.Автоматическая память (auto) – этот класс выделяется объектам блока, выделяется либо в стеке либо в регистре. Объекты этого класса имеют локальную продолжительность существования.

2.Статическая память (static) –этот класс приписан объектам явно и задает статическую продолжительность существования, память выделяется в сегменте данных.

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

Для переменных класс приписывается явно. При определении объекта ему приписывается не только тип но и класс памяти, продолжительность существования, тип связывания, область действия имени и т.д.

Явно задается только класс памяти.

Общее определение обьекта:

[класс памяти][модификатор] тип имя [инициализатор] ([] – говорит о том что то что внутри может быть опущено).

При определении объекта переменной или константы класс extern не используется. Этот класс используется при описании объектов. По определению ему задается имя, и другие атрибуты, тип, выделение памяти.

Описание – информация для транслятора об объекте.

Описание: [класс памяти][модификатор] тип имя, но без инициализатора так как это информация только для транслятора.

Рекурсия

Под рекурсивным понимают способ описания понятий процессов функции через самих себя. Рекурсивное решение предполагает разбиение(разложение) на совокупность подзадач, таким образом, что любые 2 подзадачи либо не пересекались, либо одна из них является подзадачей другой. Среди этих подзадач должна быть хотя бы одна подзадача, которая определяет тривиальный случай –случай, когда задача решается непосредственно, - хотя бы одна подзадача определяет непосредственное решение, и должна быть хотя бы одна подзадача, которая определяет общий случай решения задачи. При этом общий случай решения задачи является способом сведения общей задачи к решению одной или нескольких простых (тривиальных) задач. Общий способ решения задач – это, как правило, способ, при котором происходит снижение размерности задачи. Процесс, сведения общей задачи к простой, называют разворачиванием рекурсий. После того, как рекурсия развернута, т.е. сведена к простой задаче, которая может быть решена непосредственно, выполняется процесс сворачивания рекурсии. На этом этапе происходит обобщение простого решения и переход, таким образом, к решению сложной задачи. Глубина рекурсии – количество шагов для сведения общей задачи к частной. Используя рекурсивное решение задачи идет оценка глубины рекурсии. Поэтому, прибегать к рекурсивному решению задачи необходимо, когда сама природа задачи является рекурсивной. Это проявляется если:

1. обрабатываемые данные имеют рекурсивную природу

2. нет для задачи итеративного способа решения – в этом случае применяют метод полного или частичного перебора возможных вариантов решения задачи.

Для реализации рекурсии в я.п. предлагается механизм, состоящий в возможности обращения подпрограммы к самой себе. Когда происходит очередной вызов подпрограммы, создаются новые экземпляры (поколения) формальных параметров и внутренних (локальных) переменных. При этом определено правило доступности экземпляров переменных – на некотором уровне рекурсии или же вызове подпрограмм доступны только те экземпляры переменных, которые соответствуют этому вызову. Для реализации правила доступности переменных используется стековая память – область памяти с определенным правилом обращения к элементам. Это правило состоит в следующем – в стеке доступен тот элемент, который был помещен в него последним. Непосредственная рекурсия – когда подпрограмма вызывает сама себя. Косвенная рекурсия – существует функция А, которая вызывает функцию В, которая, в свою очередь, вызывает функцию А. В стековой памяти хранятся не только значения подпрограмм, но и для каждого уровня рекурсии хранится текущее состояние подпрограмм. Для того, чтобы избежать при рекурсивном решении повторных вычислений одних и тех же величин необходимо передавать результаты промежуточных вычислений с одного уровня рекурсии на другой. Нет общего правила выполнения для каждой задачи, в каждой задаче это решается непосредственно для этой задачи, но с использованием дополнительных переменных. Реализация решения может проходить в одной из трех форм описания рекурсивного решения:

1. говорит о том, что реализация решения осуществляется на этапе рекурсивного разворачивания (спуска)

{S; if (условие)

Вызов подпрограммы}

2. задача решается на этапе сворачивания рекурсий

{ if (условие)

Вызов подпрограммы; s}

3. когда часть задачи решается на этапе разворачивания, а часть – на этапе сворачивания

{S1; if (условие) вызов подпрограммы; S2}

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

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

Наши рекомендации