Возвращение нескольких значений
Как упоминалось выше, функции могут возвращать только одно значение. Что же делать, если нужно получить от функции сразу два значения? Один путь решения этой проблемы — передача функции двух объектов как ссылок. В ходе выполнения функция присвоит этим объектам нужные значения. Факт передачи объектов как ссылок, позволяющий функции изменить исходные объекты, равносилен разрешению данной функции возвратить два значения. В этом случае мы обходимся без возвращаемого значения, которое (зачем же пропадать добру) можно использовать для сообщения об ошибках.
И вновь одинакового результата можно достичь, используя как ссылки, так и указатели. В листинге 9.8 показана функция, которая возвращает три значения: два в виде параметров-указателей и одно в виде возвращаемого значения функции.
Листинг 9.8. Возвращение значений с помощью указателей
1: // Листинг 9.8.
2: // Возвращение нескольких значений из функции с помощью указателей
3:
4: #include
5: int
6: short Factor(int n, int* pSquared, int* pCubed);
7:
8: int main()
9: {
10: int number, squared, cubed;
11: short error;
12:
13: cout << "Enter a number (0 - 20): ";
14: cin >> number;
15:
16: error = Factor(number, &squared, &cubed);
17:
18: if (!error)
19: {
20: cout << "number: " << number << "\n";
21: cout << "square: " << squared << "\n";
22: cout << "cubed: " << cubed << "\n";
23: }
24: else
25: cout << "Error encountered!!\n";
26: return 0;
27: }
28:
29: short Factor(int n, int *pSquared, int *pCubed)
30: {
31: short Value = 0;
32: if (n > 20)
33: Value = 1;
34: else
35: {
36: *pSquared = n*n;
37: *pCubed = n*ri*n;
38: Value = 0;
39: }
40: return Value;
41: }
Результат:
Enter a number (0-20): 3
number: 3
square: 9
cubed: 27
Анализ:В строке 10 переменные number, squared и cubed определяются с использованием типа int. Переменной number присваивается значение, введенное пользователем. Это значение, а также адреса переменных squared и cubed передаются функции Factor() в виде параметров.
В функции Factor() анализируется первый параметр, который передается как значение. Если он больше 20 (максимальное значение, которое может обработать эта функция), то возвращаемое значение Value устанавливается равным единице, что служит признаком ошибки. Обратите внимание на то, что возвращаемое значение из функции Factor() может принимать либо значение 1, либо 0, являющееся признаком того, что все прошло нормально, а также заметьте, что функция возвращает это значение лишь в строке 40.
Итак, искомые значения (квадрат и куб заданного числа) возвращаются в вызывающую функцию не путем использования механизма возврата значений, а за счет изменения значений переменных, указатели которых переданы в функцию.
В строках 36 и 37 посредством указателей переменным в функции main() присваиваются возвращаемые значения. В строке 38 переменной Value присваивается значение возврата, означающее успешное завершение работы функции. В строке 40 это значение Value возвращается вызывающей функции.
Эту программу можно слегка усовершенствовать, дополнив ее следующим объявлением:
enum ERROR_VALUE { SUCCESS, FAILURE} ;
Затем вместо возврата значений 0 или 1 эта программа сможет возвращать SUCCESS ИЛИ FAILURE.
Возвращение значений с помощью ссылок
Несмотря на то что листинг 9.8 прекрасно работает, его можно упростить как для чтения, так и в эксплуатации, если вместо указателей использовать ссылки. В листинге 9.9 показана та же самая программа, но вместо указателей в качестве параметров функции в ней используются ссылки, а также добавлено упомянутое выше перечисление ERROR.
Листинг 9.9. Возвращение значений с помощью ссылок
1: // Листинг 9.9.
2: // Возвращение нескольких значений из функции
3: // с помощью ссылок
4:
5: #include
6:
7: typedef unsigned short USHORT;
8: enum ERR_CODE { SUCCESS, ERROR }
9:
10: ERR_CODE Factor(USHORT, USHORT&, USHORT&);
11:
12: int main()
13: {
14: USHORT number, sguared, cubed;
15: ERR__CODE result;
16:
17: cout << "Enter а number (0 - 20): ";
18: cin >> number;
19:
20: result = Factor(number, squared, cubed);
21:
22: if (result == SUCCESS)
23: {
24: cout << "number: " << number << "\n";
25: cout << "square: " << squared << "\n";
26: cout << "cubed: " << cubed << "\n";
27: }
28: else
29: cout << "Error encountered!!\n";
30: return 0;
31: }
32:
33: ERR_CODE Factor(USHORT n, USHORT &rSquared, USHORT &rCubed)
34: {
35: if (n > 20)
36: return ERROR; // simple error code
37: else
38: {
39: rSquared = n*n;
40: rCubed = n*n*n;
41: return SUCCESS;
42: }
43: }
Результат:
Enter a number (0 - 20): 3
number: 3
square: 9
cubed: 27
Анализ:Листинг 9.9 идентичен листингу 9.8 с двумя исключениями. Перечисление ERR_CODE делает сообщение об ошибке более явным (см. строки 36 и 41), как, впрочем, и его обработку (строка 22).
Читать дальше