Главная->Інформатика та програмування->Содержание->Передача по ссылке аргументов стандартных типов

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 5) онлайн

Передача по ссылке аргументов стандартных типов

Следующий пример, REF, демонстрирует передачу по ссылке обычной переменной.

 

// ref.cpp

// применение ссылочного механизма передачи аргументов #include <iostream> using namespace std;

int main() {

void intfrac(float, float&, float&); // прототип float number, intpart, fracpart; do {

cout << "\nВведите вещественное число:";

cin >> number; // ввод числа пользователем

intfrac(number, intpart, fracpart); // нахождение целой и дробной части cout << "Целая часть равна " << intpart // вывод результатов << ", дробная часть равна " << fracpart << endl; } while(number != 0.0 );               //выход из цикла, если введен ноль

 return 0;

} //--------------------------------------------------------

// функция intfrac()

// вычисляет целую и дробную часть вещественного числа

void intfrac(float n, float& intp, float& fracp) {

long temp = static_cast<long>(n);          // преобразование к типу long,

intp = static_cast<float>(temp);              // и обратно во float

fracp = n - intp; // вычитаем целую часть

}

 

Функция main() запрашивает у пользователя значение типа float. Затем про- грамма выделяет целую и дробную часть введенного числа. Например, если пользователь введет число 12.456, то программой будет выдано сообщение о том, что целая часть введенного значения равна 12, а дробная часть равна 0.456. Для выделения целой части числа используется функция intfrac(). Вот пример работы программы:

Введите вещественное число: 99.44

Целая часть равна 99, дробная часть равна 0.44

Некоторые компиляторы могут сгенерировать ложные знаки после десятич- ной точки у дробной части числа, например 0.440002. Это является ошибкой рабо- ты компилятора, а не программы, поэтому можете смело проигнорировать их.

как если бы они были в intfrac()

Рис. 5.7. Передача по ссылке в программе REF

Обратимся к рис. 5.7. Функция intfrac() выделяет из числа целую часть пу- тем преобразования значения, переданного параметру n, в переменную типа long с использованием явного приведения типов:

long temp = static_cast<long>(n);

В результате выполнения такого оператора в переменной temp окажется це- лая часть введенного числа, поскольку при преобразовании вещественного зна- чения к целому дробная часть будет отсечена. Затем целая часть снова преобра- зовывается в тип float:

intp = static_cast<float>(temp);

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

Функция intfrac() нашла целую и дробную часть числа, но каким образом она теперь сможет возвратить найденные значения в функцию main()? Ведь с помо-

щью оператора return можно возвратить только одно значение! Проблема реша- ется путем использования ссылочного механизма. Заголовок функции intfrac() выглядит следующим образом:

void intfrac(float n, float& intp, float& fracp) //Заголовок в определении функции

Аргументы, передаваемые по ссылке, обозначаются знаком &, который следу- ет за типом аргумента:

float& intp

Знак & означает, что intp является псевдонимом для той переменной, которая будет передана в функцию в качестве аргумента. Другими словами, используя имя intp в функции intfrac(), фактически мы оперируем значением переменной intpart функции main(). Знак & (амперсанд) символизирует ссылку, поэтому запись

float& intp

означает, что intp является ссылкой на переменную типа float. Точно так же fracp является ссылкой на переменную типа float, в нашем случае — на переменную fracpart.

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

void intfrac(float, float&, float&); // амперсанды в прототипе

Аналогичным образом знаком & отмечаются ссылочные параметры в опреде- лении функции. Однако обратите внимание на то, что при вызовах функции ам- персанды отсутствуют:

intfrac(number, intpart, fracpart); // амперсанды отсутствуют в вызове

При вызове функции нет смысла сообщать, будет ли передан аргумент по значению или по ссылке.

В то время как переменные intpart и fracpart передаются в функцию по ссылке, переменная number передается по значению. Имена intp и intpart связаны с одной и той же областью памяти, гак же как и пара имен fracp и fracpart. Параметр n не связан с переменной, передаваемой ему в качестве аргумента, поэтому ее значение копируется в переменную n. Поскольку не требуется изменять значение, храня- щееся в переменной number, передача ее в функцию осуществляется по значению.

Программистов на C, вероятно, удивляет, что знак амперсанда используется одновременно для обозначения ссылки на переменную и операции взятия адре- са переменной. Мы рассмотрим вопрос использования амперсанда в главе 10 «Указатели».

 

19