Московский государственный университет имени М.В.Ломоносова
Опубликован: 01.11.2004 | Доступ: свободный | Студентов: 10561 / 332 | Оценка: 4.12 / 4.01 | Длительность: 19:18:00
ISBN: 978-5-9556-0077-9
Специальности: Программист
Лекция 5:

Управление данными и параметрами подпрограмм

< Лекция 4 || Лекция 5: 12 || Лекция 6 >

Передача параметров

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

Различаются следующие способы передачи параметров: по ссылке, по имени, по значению, по значению-результату, по результату, по значению-константе. Набор допустимых способов передачи параметров зависит от конкретного языка программирования.

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

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

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

При передаче параметров по значению-результату измененное значение фактического параметра возвращается вызывающей подпрограмме. Однако, в отличие от передачи параметров по ссылке, при данном способе сначала в момент вызова подпрограммы значение фактического параметра присваивается соответствующему формальному параметру вызываемой подпрограммы, и все изменения выполняются над формальным параметром, а не над ссылкой на фактический параметр. При завершении вызываемой подпрограммы текущее значение формального параметра присваивается обратно фактическому параметру. Такой тип передачи параметров был применен в языке ALGOL-W.

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

При передаче параметров по значению-константе значение фактического параметра не может быть изменено. Такой способ передачи параметров может быть реализован и как частный случай передачи параметра по значению, и как передача параметра по ссылке на константное выражение, что однозначно гарантирует неизменность фактического параметра вызывающей подпрограммы.

В большинстве случаев языки программирования используют один или два способа передачи параметров. Так, язык программирования С позволяет только передачу параметров по значению (ссылка реализуется как значение указателя). В языке программирования Pascal допускается два способа передачи параметров: по значению и по ссылке.

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

Способ передачи параметров Pascal C
Передача параметров по значению
procedure P1(i: integer);
begin
 i:=0;
end;
// Передача значения
void P1(int i)
{i=0; }
//Вызов подпрограммы
i=10;
P1(i);
Передача параметров по ссылке
procedure P1(var i: integer);
begin
 i:=0;
end;
// Передача указателя на значение
void P1(int *i)
  { *i=*i+1;}
//Вызов подпрограммы
i=10;
P1(&i);

Существующие в настоящее время средства автоматической генерации кода вызова подпрограммы по описанию интерфейса вводят понятие входных и выходных параметров (помечаемых как in и out ). При этом в зависимости от типа параметра и определения его как входного и/или выходного компилятор автоматически выбирает подходящий для данной реализации способ передачи параметров.

Функции и процедуры

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

Если подпрограмма реализуется как функция, то она при завершении должна возвращать значение определенного типа (например, return 0; ). Подпрограмма-функция может указываться в выражениях.

Подпрограмма-функция также может быть передана подпрограмме в качестве фактического параметра, например,

(procedure P1 (i: integer; 
    function P2(j:integer):integer);).

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

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

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

< Лекция 4 || Лекция 5: 12 || Лекция 6 >
Александр Демьяненко
Александр Демьяненко

Можно ли сдавать один и тот же тест несколько раз?
Или же один и тот же тест можно сдать лишь однажды?

Максим Стогний
Максим Стогний

Добрый день!

Скажите, пожалуйста, если в терминологии объектно-ориентированного программирования функции также называются методами или методами - членами класса, в примере объявления указателя на метод использовали в формальном описании оба названия:

тип_метода (имя_класса::*имя_метода_указателя)
    (список параметров);
тип_функции (*имя_ функции_указателя)
    (список параметров);

при этом можно было  тип_функции во втором описании заменить на тип_метода? Т.е.:

тип_метода (*имя_ метода_указателя)
    (список параметров);

Анатолий Гречман
Анатолий Гречман
Казахстан, Экибастуз, Экибастузский Инженерно-технический Институт, 2014
Berkut Molodoy
Berkut Molodoy
Россия