Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КРАТКИЙ ОБЗОР С.doc
Скачиваний:
1
Добавлен:
26.10.2018
Размер:
2.11 Mб
Скачать

4.6.3 Передача параметров

      При вызове функции выделяется память для ее формальных параметров,       и каждый формальный параметр инициализируется значением       соответствующего фактического параметра. Семантика передачи       параметров тождественна семантике инициализации. В частности, сверяются       типы формального и соответствующего ему фактического параметра, и       выполняются все стандартные и пользовательские преобразования типа.       Существуют специальные правила передачи массивов ($$4.6.5).       Есть возможность передать параметр, минуя контроль типа ($$4.6.8),       и возможность задать стандартное значение параметра ($$4.6.7).       Рассмотрим функцию:       void f(int val, int& ref)       {       val++;       ref++;       }       При вызове f() в выражении val++ увеличивается локальная копия       первого фактического параметра, тогда как в ref++ - сам второй       фактический параметр увеличивается сам. Поэтому в функции       void g()       {       int i = 1;       int j = 1;       f(i,j);       }       увеличится значение j, но не i. Первый параметр i передается по       значению, а второй параметр j передается по ссылке. В $$2.3.10       мы говорили, что функции, которые изменяют свой передаваемый       по ссылке параметр, труднее понять, и что поэтому лучше их избегать       (см. также $$10.2.2). Но большие объекты, очевидно, гораздо       эффективнее передавать по ссылке, чем по значению. Правда можно       описать параметр со спецификацией const, чтобы гарантировать, что       передача по ссылке используется только для эффективности, и       вызываемая функция не может изменить значение объекта:       void f(const large& arg)       {       // значение "arg" нельзя изменить без явных       // операций преобразования типа       }       Если в описании параметра ссылки const не указано, то это       рассматривается как намерение изменять передаваемый объект:       void g(large& arg); // считается, что в g() arg будет меняться       Отсюда мораль: используйте const всюду, где возможно.       Точно так же, описание параметра, являющегося указателем, со       спецификацией const говорит о том, что указуемый объект не будет       изменяться в вызываемой функции. Например:       extern int strlen(const char*); // из <string.h>       extern char* strcpy(char* to, const char* from);       extern int strcmp(const char*, const char*);       Значение такого приема растет вместе с ростом программы.       Отметим, что семантика передачи параметров отличается от семантики       присваивания. Это различие существенно для параметров, являющихся       const или ссылкой, а также для параметров с типом, определенным       пользователем ($1.4.2).       Литерал, константу и параметр, требующий преобразования,       можно передавать как параметр типа const&, но без спецификации       const передавать нельзя. Допуская преобразования для параметра типа       const T&, мы гарантируем, что он может принимать значения из того же       множества, что и параметр типа T, значение которого передается       при необходимости с помощью временной переменной.       float fsqrt(const float&); // функция sqrt в стиле Фортрана       void g(double d)       {       float r;       r = fsqrt(2.0f); // передача ссылки на временную       // переменную, содержащую 2.0f       r = fsqrt(r); // передача ссылки на r       r = fsqrt(d); // передача ссылки на временную       // переменную, содержащую float(d)       }       Запрет на преобразования типа для параметров-ссылок без спецификации       const введен для того, чтобы избежать нелепых ошибок, связанных       с использованием при передаче параметров временных переменных:       void update(float& i);       void g(double d)       {       float r;       update(2.0f); // ошибка: параметр-константа       update(r); // нормально: передается ссылка на r       update(d); // ошибка: здесь нужно преобразовывать тип       }