Параметр (программирование)

Перейти к навигацииПерейти к поиску

Пара́метр в программировании — принятый функцией аргумент. Термин «аргумент» подразумевает, что конкретно и какой конкретной функции было передано, а параметр — в каком качестве функция применила это принятое. То есть вызывающий код передает аргумент в параметр, который определен в члене спецификации функции.

Формальные и фактические параметры

Важно различать:

  • формальный параметр — аргумент, указываемый при объявлении или определении функции.[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-выражение).

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

Таким образом можно ожидать, что примерная программа напечатает (если закомментировать ошибочную строку) «0010 022 233 333».

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

Язык Fortran подразумевает передачу параметров исключительно по ссылке:

См. также

Литература

  • В.В.Фаронов. 8.2.2. Параметры // 8.2. Описание подпрограммы // Глава 8. Процедуры и функции // Иллюстрированный самоучитель по Турбо Паскалю.

Ссылки

  1. The GNU C Programming - Actual parameters and formal parameters (англ.). Дата обращения: 13 октября 2012. Архивировано 16 февраля 2020 года.
  2. Определение и вызов функций. Дата обращения: 13 октября 2012. Архивировано 28 августа 2012 года.
  3. Fredrik Lundh. Call By Object (англ.). effbot.org. Дата обращения: 29 мая 2014. Архивировано из оригинала 23 ноября 2019 года.
  4. Iota Language Definition. CS 412/413 Introduction to Compilers. Cornell University (2001). Дата обращения: 29 мая 2014. Архивировано 23 сентября 2015 года.