Передача Параметров
Когда вызывается функция, дополнительно выделяется память под ее формальные параметры, и каждый формальный параметр инициализируется соответствующим ему фактическим параметром. Семантика передачи параметров идентична семантике инициализации. В частности, тип фактического параметра сопоставляется с типом формального параметра, и выполняются все стандартные и определенные пользователем преобразования типов. Есть особые правила для передачи векторов (#4.6.5), средство передавать параметр без проверки (#4.6.8) и средство для задания параметров по умолчанию (#4.6.6). Рассмотрим
void f(int val, int ref) { val++; ref++; }
Когда вызывается f(), val++ увеличивает локальную копию первого фактического параметра, тогда как ref++ увеличивает второй фактический параметр. Например:
int i = 1; int j = 1; f(i,j);
увеличивает j, но не i. Первый параметр, i, передается по значению, второй параметр, j, передается по ссылке. Как уже отмечалось в #2.3.10, использование функций, которые изменяют переданные по ссылке параметры, могут сделать программу трудно читаемой, и их следует избегать (но см. и #8.4). Однако передача большого объекта по ссылке может быть гораздо эффективнее, чем передача его по значению. В этом случае параметр можно описать как const, чтобы указать, что ссылка применяется по соображениям эффективности, а также чтобы не позволить вызываемой функции изменять значение объекта:
void f(const large arg) { // значение "arg" не может быть изменено }
Аналогично, описание параметра указателя как const сообщает читателю, что значение объекта, указываемого указателем, функцией не изменяется. Например:
extern int strlen(const char*); // из extern char* strcpy(char* to, const char* from); extern int strcmp(const char*, const char*);
Важность такой практики растет с размером программы.
Заметьте, что семантика передачи параметров отлична от семантики присваивания. Это важно для const параметров, ссылочных параметров и параметров некоторых типов, определяемых пользователем (#6.6).