Параметры и аргументы

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

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

// предупреждения
double d = 5.5;
Fibo(d);          // possible loss of data due to type conversion
Fibo(5.5);        // truncation of constant value
Fibo("10");       // implicit conversion from 'string' to 'number'
// ошибки
Fibo();           // wrong parameters count
Fibo(010);      // wrong parameters count

Все предупреждения касаются неявных преобразований, которые компилятор выполняет из-за того, что типы значений не соответствуют типам параметров. Их следует расценивать как потенциальные ошибки и устранять. Ошибка "неверное количество параметров" ("wrong parameters count") возникает, когда аргументов слишком мало или слишком много.

В принципе, параметр функции не обязан иметь имя, то есть для описания параметра достаточно только типа. Это звучит довольно странно, потому что к параметру без имени мы не сможем обращаться внутри функции. Однако при создании программ, основывающихся на неких стандартных интерфейсах, иногда приходится писать функции, которые должны отвечать заданным прототипам. При этом внутри функции некоторые параметры могут оказаться ненужными. Тогда для явного указания этого факта программист может опустить их имена. Например, MQL5 API предписывает реализовывать функцию-обработчик события OnDeinit со следующим прототипом:

void OnDeinit(const int reason);

Если в коде функции нам не требуется параметр reason, мы можем опустить его в описании:

void OnDeinit(const int);

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