1611678431-0e68e83522cb9d960ac896aa5d90854d (826635), страница 12
Текст из файла (страница 12)
д.);формальный параметр — аргумент, используемый как ячейка памяти(название переменной, указатель на переменную), выступающее в качестве идентификатораэтого значения, принимаемого функцией.Определяющим отличием формального от фактического параметра является доступ к самойпеременной аргумента (обращение к памяти), в то время как фактический параметр его не имеет,так как копирует в оперативную память его значение, и пользуется именно им.Особенности использования:формального параметра:аргумент должен быть определён вне функции;параметр формирует побочный эффект;размера вектора может не описываться, тогда доступ осуществляется либо по указателям,либо с помощью специальных средств языка;фактического параметра-переменной — копировании в оперативную память.
Еслифактический параметр не подлежит изменению, для экономии памяти его можно оформитьконстантой (константы вычисляются и инициализируются на этапе компиляции).Поддержка: некоторые языки не имеет специальных лексических средств поддержкиформирования формальных, например Си/Си++, или фактических параметров.Пример на языке Паскаль: [скрыть]Program parameter(output);var iActual, iFormal: Integer;Function actual_p(n: Integer): Integer;begin {actual_p}n := 1;actual_p := n;end {actual_p};Function formal_p(var n: Integer): Integer;begin {formal_p}n := 1;formal_p := n;end {formal_p};beginiActual := 0;iFormal := 0;WriteLn('Начальное значение переменной: ', iActual);WriteLn('Аргумент передан как фактический параметр и изменён:', actual_p(iActual));WriteLn('Конечное значение переменной: ', iActual);WriteLn('Начальное значение переменной: ', iFormal);WriteLn('Аргумент передан как формальный параметр и изменён:', formal_p(iFormal));WriteLn('Конечное значение переменной: ', iFormal);ReadLn; { Ожидание нажатия кнопики и enter, для закрытия окна.
}end.Пример на языке С++: [скрыть]#include <iostream>using namespace std;int actual_p(int n){n = 1;return n;}int formal_p(int &n){n = 1;return n;}int main(){int iActual = 0;int iFormal = 0;cout << "Начальное значение переменной: " << iActual << endl;cout << "Аргумент передан как фактический параметр и изменён: " <<actual_p(iActual) << endl;cout << "Конечное значение переменной: " << iActual << endl;cout << "Начальное значение переменной: " << iFormal << endl;cout << "Аргумент передан как формальный параметр и изменён: " <<formal_p(iFormal) << endl;cout << "Конечное значение переменной: " << iFormal << endl;return 0;}Результат работы программ:Начальное значение переменной: 0Аргумент передан как фактический параметр и изменён: 1Конечное значение переменной: 0Начальное значение переменной: 0Аргумент передан как формальный параметр и изменён: 1Конечное значение переменной: 1Как видно из работы программ:фактический параметр — значение аргумента;формальный параметр — имя аргумента, то есть указатель на переменную.Передача параметраПередача параметра возможна по значению и по ссылке.
Иногда также используют выражение«передача параметра по адресу». Ниже приведён пример, иллюстрирующий различия этихспособов.[править]Передачапараметра по значениюПередача параметра по значению означает что вызывающая функция копирует в память,доступную вызываемой, (обычно стек) непосредственное значение. Изменение копиипеременной, соответственно, оригинал не затрагивает.[править]Передачапараметра по адресуЕсли необходимо именно изменить переменную из внешней, по отношению к вызываемойфункции, области видимости, можно копировать адрес переменной, подлежащей изменению.Соответственно при вызове функции g(&x) приходится использовать операцию взятияадреса. Эта техническая деталь отвлекает внимание программиста от логики прикладнойпрограммы, однако в случаях невозможности передачи по ссылке может оказаться единственнымрешением.Можно заметить, что передача параметра по адресу является частным случаем передачи позначению: передаваемым значением является адрес, по которому можно найти другое значение —значение переменной x.[править]Передачапараметра по ссылкеПередача параметра по ссылке означает что копируется не само значение,а адрес исходной переменной (как в случае передачи параметра по адресу), однако синтаксисиспользуется такой, чтобы программисту не приходилось использоватьоперацию разыменования и он мог иметь дело непосредственно со значением, хранящимся поэтому адресу (как в случае передачи параметра по значению).Передача по ссылке позволяет избежать копирования всей информации, описывающейсостояние объекта (а это может быть существенно больше чем sizeof(int)) и являетсянеобходимой для конструктора копирования.Если функция возвращает значение по ссылке (например, в виде «return *this;»), то её вызовможно использовать слева от оператора присваивания (смотри также L-выражение).В случае если передача по ссылке используется именно как средство увеличения быстродействия,но изменение параметра нежелательно, можно использовать передачу по ссылке константногообъекта.Таким образом можно ожидать, что примерная программа напечатает (если закоментироватьошибочную строку) «0010 022 233 333».Некоторые языки (или их диалекты) не поддерживают передачу по ссылке, некоторые наоборот передают параметры исключительно по ссылке, что порождает риск непреднамеренногоизменения контекста вызывающей функции.27.
Входные и выходные параметры, параметры-подпрограммы6.1.3 Изменение действия -- входные параметрыПолезность процедуры значительно возрастает, если ее действие можноизменять от одного вызова к другому. Это достигается с помощью механизмапараметров.Часть из них -- это переменные, локализованные внутри процедуры ипринимающие различные начальные значения при разных вызовах. Этипараметры называются входными (илипараметрами-значениями). Типы и видывсех параметров процедуры определяются в списке формальных параметров(рис. 6.2), размещаемом в круглых скобках после имени процедуры в еезаголовке, в котором спецификация входных формальных параметров задается всоответствии с диаграммой рис. 6.3.FormalParameters = "(" [ FPSection { ";" FPSection } ] ")" [ ":" FormalType ].FPSection = ( InFPSection | OutFPSection ).Рис.
6.2. Синтаксис формальных парамерных параметровInFPSection = ident { "," ident } ":" FormalType.Рис. 6.3. Спецификация входных формальных параметровТаким образом, если процедуру Линия необходимо вызывать для рисованияразными символами строк разной длины, то в ней необходимо завести двапараметра. Такая процедура используется в программе ГИСТОГРАММА,приведенной ниже. Программа читает непустую последовательность, гдесостоит из abs("умножить", если-- целые числа, и рисует)+1 знаков "минус", еслистрок, -я из которых, и из 100 знаков.module Гистограмма;const N = 100;var K,M : iteger; A : integer;procedure Линия (N:integer; Знак:char);var I : integer;begin for I := 1 to N do write(Знак) end; writeln end Линия;beginread(M);for K := 1 to M doread(A);if A > N then Линия (N,' ') else Линия(abs(A)+1, '-') endendend Гистограмма.Различные значения, присваиваемые в качестве начальных значенийформальным параметрам, задаются в операторах вызова выражениями,называемыми фактическими параметрами.
Длина списка фактическихпараметров в операторе вызова (заметим, что фактические параметры в спискеразделяются запятой, а формальные -- точкой с запятой) должна совпадать сдлиной списка формальных параметров в описании вызываемой подпрограммы.Причем в этих списках должны совпадать типы любых двух параметров,расположенных на одних и тех же позициях в списках; такие параметрыназываются соответствующими.
В момент вызова каждый фактическийпараметр вычисляется и его значение присваивается соответствующемуформальному параметру.6.1.4 Получение результатов -- выходные параметрыДействие, реализуемое процедурой, может при разных вызовах приводить кизменению значений разных переменных. Это достигается спомощью выходных параметров (или параметров-переменных). При вызовепроцедуры фактический параметр, соответствующий выходному формальномупараметру, должен быть переменной (вспомним, например, фактическиепараметры стандартной процедуры).