624_____________________________________________Глава 11

Если значение параметра п равно 0 или 1, то функция возвращает значение 1.
В противном случае функция умножает текущее значение п на результат, возвра-
щаемый вызовом той же функции factorial, но со значением параметра п, умень-
шенным на единицу. Поскольку при каждом вызове значение параметра уменьша-
ется, рано или поздно оно станет равно 1. После этого цепочка рекурсивных вызо-
вов начнет свертываться и в конце концов вернет значение факториала.

11.5.2 Передача параметров в функции по значению
и по ссылке

Список параметров, передаваемый в функции, как было показано в предыду-
щем разделе, состоит из имен параметров и указаний на их тип. Например, в заго-
ловке

double FSumfdouble XI,double X2, int A)

указано три параметра XI, X2, А и определены их типы. Вызов такой процедуры
может иметь вид:

Pr(Y, X2, 5);

Это только один из способов передачи параметров в процедуру, называемый
передачей по значению. Работает он так. В момент вызова функции в памяти со-
здаются временные переменные с именами XI, X2, А, и в них копируются значе-
ния аргументов Y, X2 и константы 5. На этом связь между аргументами и пере-
менными XI, X2, А разрывается. Вы можете изменять внутри процедуры значе-
ния XI, X2 и А, но это никак не отразится на значениях аргументов. Аргументы
при этом надежно защищены от непреднамеренного изменения своих значений
вызванной функцией. Это предотвращает случайные побочные эффекты, которые
так сильно мешают иногда созданию корректного и надежного программного обес-
печения.

К недостаткам такой передачи параметров по значению относятся затраты
времени на копирование значений и затраты памяти для хранения копии. Если
речь идет о какой-то переменной простого типа, это, конечно, не существенно. Но
если, например, аргумент — массив из тысяч элементов, то соображения затрат
времени и памяти могут стать существенными.

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

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

Вызов по ссылке можно осуществить двумя способами: с помощью ссылочных
параметров и с помощью указателей. Ссылочный параметр — это псевдоним соот-
ветствующего аргумента. Чтобы показать, что параметр функции передан по ссыл-
ке, после типа параметра в прототипе функции ставится символ амперсанта (&);

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

int scount
int & count
ints count