Ссылки в качестве параметров функций
Cами по себе ссылочные переменные используются довольно редко. В качестве параметров функции ссылки имеют более широкое применение и предлагают полезную альтернативу доступа к параметрам. Ссылки особенно полезны в функциях, возвращающих несколько объектов, например два или более вводимых значения. Листинг 1.16 —введите сумму платежей и налогов после их запроса. Программа выведет цену и сумму налога на введенные вами значения. Листинг 1.16. TAX.CPP (использование ссылок в качестве параметров функции) 1: #include <iostream.h> 2: 3: #include <stdlib.h> 4: #include <stdio.h> 5: 6: double GetDouble(const char *prompt); 7: void GetData(double &paid, double &rate); 8: void Calculate(const double paid, const double rate, 9: double &list, double &tax); 10: 11: main() 12: { 13: double paid, rate, list, tax; 14: GetData(paid, rate); 15: Calculate(paid, rate, list, tax); 16: printf("List pride = $%8.2f\n", list); 17: printf("Tax paid = $%8.2f\n", tax); 18: return 0; 19:} 21: // Возвращает одно вещественное значение двойной точности 22: double GetDouble(const char *prompt) 23: { 24: char s[20]; // Строка для ввода 25: printf(prompt); // Отображение строки запроса 26: scanf("%20s", s); // Ввести данные как строку 27: return atof(s); // Возвратить введенные данные 28: } 29: 30: // Ввод цены и ставки налога вещественными значениями двойной точности 31: // Замечание: изменяет значение paid и rate 32: void GetData(double &paid, double &rate) 33: { 34: paid = GetDouble("Price paid?"); 35: rate = GetDouble("Tax rate (ex: .06)?"); 36: } 37: 38: // Вычисляет цену и налог no сумме и ставке 39: // Замечание: изменяет значение list и tax 40: void Calculate(const double paid, const double rate, 41: double &list, double &tax) 42: { 43: list = paid / (1 + rate); 44: tax = paid - list; 45:} В программе определены три функции. Первая функция запрашивает и возвращает вещественное значение двойной точности — обычное описание функции, возвращающей некоторое значение: double GetDouble(const char *prompt); Вторая функция демонстрирует использование ссылочных параметров для возврата двух или более значений. Заметьте, что обоим параметрам функции предшествует символ &, означающий, что эти параметры передаются по ссылке (т.е. в GetData передаются их адреса вместо значений): void GetData (double &paid, double &rate); Рассмотрим тело функции GetData. В нем дважды вызывается GetDouble с аргументом-строкой, которая должна отображаться, и полученные значения присваиваются ссылочным параметрам paid и rate: paid - GetDouble("Price paid?"); rate = GetDouble("Tax rate (ex: .06)?"); Поскольку paid и rate — ссылки, значения присваиваются объектам, переданным функции GetDouble(). Например, в функции main() следующий оператор вводит значения в две переменные, также названные paid и rate: GetData(paid, rate); Некоторые критикуют передачу параметров функции по ссылке, верно замечая, что такие вызовы выглядят обманчиво, поскольку аргументы в них передаются посылке неявно. Ключ к решению этой проблемы и эффективному использованию ссылочных параметров — хорошее документирование программ. Обязательно должен присутствовать комментарий, в котором указывается, что вызов GetData изменяет значения paid и rate. Третья, и последняя, функция в примере вычисляет цену и налог к уплате, основываясь на действительной цене и ставке налога. Первых два параметра, paid и rate, — входные параметры функции. Поскольку функция не изменяет их, они объявлены константами, и передаются только их значения (точнее, копии их значений). Вторых два параметра, list и tax, — это выходные значения функции. Эти значения изменяются функцией и, следовательно, передаются по ссылке: void Calculate(const double paid, const double rate, double &list, double &tax) Функция Calculate присваивает новые значения list и tax в следующих операторах: list = paid / (1 + rate); tax = paid - list; Поскольку параметры — ссылки, в действительности используются переменные, переданные функции Calculate(). Операция присваивания происходит по ссылке, вследствие чего изменяются действительные переменные, когда в функции main происходит следующий вызов: Calculate(paid, rate, list, tax); Аргументы, передающиеся по значению, невозможно отличить от аргументов, передающихся по ссылке. Хорошее документирование функции Calculate уменьшит опасность подобных ошибок. Ссылки и указатели в качестве параметров тесно связаны. В самом деле, ссылки могут интерпретироваться компилятором С++ как указатели. Для того чтобы вникнуть в суть этой идеи, рассмотрим следующую небольшую функцию: void f(int *ip) *ip = 1234; Внутри этой функции осуществляется доступ к переданному аргументу, адрес которого хранится в указателе ip, с помощью оператора вида f(&ivar); // Передача адреса ivar Внутри функции выражение *ip = 1234; присваивает значение 1234 переменной ivar, адрес которой передается функции f(). Теперь рассмотрим аналогичную функцию, использующую ссылочные параметры: void f(int &ir) { ir = 1234; } Указатель ip заменен ссылкой ir, которой функция присваивает 1234. Выражение f(ivar); // Передача ivar по ссылке присваивает значение ссылочному объекту: передает ivar по ссылке функции f(), и поскольку ir ссылается на ivar, то ivar присваивается 1234. ©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|