Параметр (программирование)
Из Википедии, бесплатной энциклопедии
Пара́метр в программировании — принятый функцией аргумент. Термин «аргумент» подразумевает, что конкретно и какой конкретной функции было передано, а параметр — в каком качестве функция применила это принятое. То есть вызывающий код передает аргумент в параметр, который определен в члене спецификации функции.
Формальные и фактические параметры
[править | править код]Важно различать:
- формальный параметр — аргумент, указываемый при объявлении или определении функции.[1][2]
- фактический параметр — аргумент, передаваемый в функцию при её вызове;
Пример на языке Си:
// Описание функции. int a - формальный параметр, имя параметра может отсутствовать. int myfunction(int a); // Определение функции. int b - формальный параметр, имя параметра может не совпадать с указанным при объявлении функции. int myfunction(int b) { return 0; } int main() { int c=0; myfunction(c); // Вызов функции. c - фактический параметр. return 0; }
Использование параметров
[править | править код]Семантика использования формальных и фактических параметров называется стратегией вычисления. Заданная стратегия вычисления диктует, когда следует вычислять аргументы функции (метода, операции, отношения), и какие значения следует передавать. Существует довольно много разнообразных стратегий вычисления.
Примечание — использование распространённого в сообществе императивного программирования термина «передача параметра» для многих языков программирования является не вполне корректным — например, в случае вызова по необходимости, применяемого в языке Haskell, параметр может быть использован в теле функции, но ни разу не передан за все случаи её вызова, и даже полностью исключён из результирующего машинного кода.
Наиболее часто упоминаемыми стратегиями вычисления являются вызов по значению и вызов по ссылке, однако в действительности использование этих терминов не всегда уместно. Например, в сообществе языка Java говорят «Java использует вызов по значению, где „значением“ является ссылка на объект», в сообществе языка Ruby говорят «Ruby использует вызов по ссылке», однако в действительности оба эти языка используют стратегию вызов по соиспользованию (англ. call-by-sharing)[3][4]. Многие языки, например Си, не имеют механизма вызова по ссылке, но позволяют симулировать его внутри семантики вызова по значению посредством ссылочных типов, в частности, указателей. В последнем случае в сообществах таких языков часто говорят «язык поддерживает две стратегии вычисления», а также о «вызове по указателю» или «вызове по адресу».
На практике, модель вычисления многих промышленных языков (Java, C#) сводится к стратегии «вызов-при-упоминании/передача-по-ссылке». Некоторые более старые языки, в особенности небезопасные языки, такие как C++, сочетают несколько разных моделей вызова, включая экзотичные, такие как «вызов-по-ссылке-на-константу». Исторически вызов по значению и вызов по имени восходят к Алголу-60, созданному в конце 1950-х годов. Только чистые функциональные языки, такие как Clean и Haskell, используют вызов по необходимости (англ. call-by-need), который часто отождествляют (что также не вполне корректно) с ленивыми вычислениями.
Примеры
[править | править код]Передача параметра по ссылке означает что копируется не само значение, а адрес исходной переменной (как в случае передачи параметра по адресу), однако синтаксис используется такой, чтобы программисту не приходилось использовать операцию разыменования и он мог иметь дело непосредственно со значением, хранящимся по этому адресу (как в случае передачи параметра по значению).
Передача по ссылке позволяет избежать копирования всей информации, описывающей состояние объекта (а это может быть существенно больше чем sizeof(int)) и является необходимой для конструктора копирования.
Если функция возвращает значение по ссылке (например, в виде «return *this;»), то её вызов можно использовать слева от оператора присваивания (см. также L-выражение).
В случае, если передача по ссылке используется именно как средство увеличения быстродействия, но изменение параметра нежелательно, можно использовать передачу по ссылке константного объекта.
#include <iostream> using namespace std; // для использования cout void f(int x) { // передача параметра по значению cout << x; x = 1; cout << x; } void g(int* x) { // передача параметра по адресу cout << *x; *x = 2; cout << *x; } void h(int& x) { // передача параметра по ссылке cout << x; x = 3; cout << x; } void i(const int& x) { // передача неизменяемого параметра по ссылке cout << x; x = 4; //Ошибка из-за которой код не будет скомпилирован cout << x; } int main() { int x = 0; cout << x; f(x); cout<< x << " "; g(&x); cout << x << " "; h(x); cout << x << " "; i(x); cout << x; return 0; }
Таким образом можно ожидать, что примерная программа напечатает (если закомментировать ошибочную строку) «0010 022 233 333».
Некоторые языки (или их диалекты) не поддерживают передачу по ссылке, некоторые наоборот — передают параметры исключительно по ссылке, что порождает риск непреднамеренного изменения контекста вызывающей функции.
Язык Fortran подразумевает передачу параметров исключительно по ссылке:
Программа:
PROGRAM PARAMS IMPLICIT NONE INTEGER A, B, C A = 7.0 B = 9.0 C = 0.0 100 FORMAT('A =',I2,', B =',I2,', C =',I3) WRITE(*, 100) A, B, C CALL MUL(A, B, C) WRITE(*, 100) A, B, C END PROGRAM SUBROUTINE MUL(A, B, C) INTEGER A, B, C C = A * B END SUBROUTINE
Напечатает:
A = 7, B = 9, C = 0 A = 7, B = 9, C = 63
См. также
[править | править код]Литература
[править | править код]- В.В.Фаронов. 8.2.2. Параметры // 8.2. Описание подпрограммы // Глава 8. Процедуры и функции // Иллюстрированный самоучитель по Турбо Паскалю.
Ссылки
[править | править код]- ↑ The GNU C Programming - Actual parameters and formal parameters (англ.). Дата обращения: 13 октября 2012. Архивировано 16 февраля 2020 года.
- ↑ Определение и вызов функций . Дата обращения: 13 октября 2012. Архивировано 28 августа 2012 года.
- ↑ Fredrik Lundh. Call By Object (англ.). effbot.org. Дата обращения: 29 мая 2014. Архивировано из оригинала 23 ноября 2019 года.
- ↑ Iota Language Definition . CS 412/413 Introduction to Compilers. Cornell University (2001). Дата обращения: 29 мая 2014. Архивировано 23 сентября 2015 года.
![]() | В статье не хватает ссылок на источники (см. рекомендации по поиску). |