Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

8.1. Способи передачі аргументів функціям

Щоб зрозуміти походження посилання, необхідно знати теорію процесу передачі аргументів функціям. У загальному випадку в мовах програмування, як правило, передбачається два способи, які дають змогу передавати аргументи в підпрограми (функції, методи, процедури). Перший називається викликом за значенням (call-by-value). У цьому випадку значення аргументу копіюється у формальний параметр підпрограми. Значить зміни, внесені в параметри підпрограми, не впливають на аргументи, що використовуються під час її виклику.

Під час виклику функції за значенням передається значення аргументу.

Другий спосіб передачі аргументу підпрограмі називається викликом за посиланням (call-by-reference). У цьому випадку в параметр копіюється адреса аргументу (а не його значення). У межах підпрограми, що викликається, цю адресу використовують для доступу до реального аргументу, що задається під час її виклику. Це означає, що зміни, внесені в параметр, нададуть дію на аргумент, що використовується під час виклику підпрограми.

Під час виклику функції за посиланням передається адреса аргументу.

8.1.1. Механізм передачі аргументів у мові програмування C++

За замовчуванням для передачі аргументів у мові програмування C++ використовується метод виклику за значенням. Це означає, що в загальному випадку код функції не може змінити аргументи, що використовуються під час виклику функції. В усіх програмах цього навчального посібника, представлених дотепер, використовувався метод виклику за значенням.

Розглянемо таку функцію.

Код програми 8.1. Демонстрація механізму передачі аргументів у мові програмування C++

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

int sqr_fun(int x);

int main()

{

int t=10;

cout << "t^2=" << sqr_fun(t) << "; t=" << t;

getch(); return 0;

}

int sqr_fun(int x)

{

x = x*x;

return x;

}

У наведеному прикладі значення аргументу 10, що передається функції sqr_fun(), копіюється в параметр х. У процесі її виконання присвоєння х = х*x змінюється тільки локальній змінній х. Змінна t, використовувана під час виклику функції sqr_fun(), як і раніше, матиме значення 10 і на неї ніяк не вплинуть операції, що виконуються у цій функції. Отже, після запуску цієї програми на екран монітора буде виведено такий результат: t^2=100; t=10.

Необхідно пам'ятати! За замовчуванням функції передається копія аргументу. Те, що відбувається усередині функції, ніяк не відображається на значенні змінної, що використовується під час виклику функції.

8.1.2. Використання покажчика для забезпечення виклику за посиланням

Незважаючи на те, що як С++-узгодження про передачу параметрів за замовчуванням діє виклик за значенням, існує можливість "вручну" замінити його викликом за посиланням. У цьому випадку функції передаватиметься адреса аргументу (тобто покажчик на аргумент). Це дасть змогу внутрішньому коду функції змінити значення аргументу, яке зберігається поза функцією. Приклад такого "дистанційного" керування значеннями змінних було показано в попередньому розділі під час перегляду можливості виклику функції з покажчиками (у прикладі коду програми функції передавався покажчик на цілочисельну змінну). Як уже зазначалося вище, покажчики передаються функціям подібно до значень будь-якого іншого типу. Безумовно, для цього необхідно оголосити параметри з типом покажчиків.

Щоб зрозуміти, як передача покажчика дає змогу вручну забезпечити виклик за посиланням, розглянемо таку версію функції swap(). Вона змінює значення двох змінних, на які вказують її аргументи.

void swap(int *x, int *y)

{

int tmp;

tmp = *x; // Тимчасово зберігаємо значення, розташоване за адресою х.

*x = *y; // Поміщаємо значення, що зберігається

// за адресою y, за адресою х.

*y = tmp; // Поміщаємо значення, яке раніше зберігалося

// за адресою х, за адресою у.

}

Тут параметри *x і *y означають змінні, що адресуються покажчиками x і y, які просто є адресами аргументів, що використовуються під час виклику функції swap(). Отже, у процесі виконання цієї функції буде зроблено реальний обмін вмістом змінних, що використовуються під час її виклику.

Оскільки функція swap() чекає, щоб отримати два покажчики, то програміст повинен пам'ятати, що функцію swap() необхідно викликати з адресами змінних, значення яких він хочете обміняти. Коректний виклик цієї функції продемонстровано у наведеному нижче коді програми.

Код програми 8.2. Демонстрація механізму використання покажчика для забезпечення виклику за посиланням

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

// Оголошуємо функцію swap(), яка використовує покажчики.

void swap(int *x, int *y);

int main()

{

int izm, jzm;

izm = 10; jzm = 20;

cout << "Початкові значення змінних izm та jzm: ";

cout << izm << " " << jzm << "\n";

swap(&jzm, &izm);//Викликаємо swap() з адресами змінних izm та jzm.

cout << "Значення змінних izm та jzm після обміну: ";

cout << izm << " " << jzm << "\n";

getch(); return 0;

}

// Обмін аргументами.

void swap(int *x, int *y)

{

int tmp;

tmp = *x; // Тимчасово зберігаємо значення за адресою х.

*x = *y; // Поміщаємо значення, збережене раніше за адресою y,

// за адресою х.

*y = tmp; // Поміщаємо значення, яке раніше зберігалося

// за адресою х, за адресою у.

}

Результати виконання цієї програми є такими:

Початкові значення змінних izm та jzm: 10 20

Значення змінних izm та jzm після обміну: 20 10

У наведеному прикладі змінній izm було присвоєне початкове значення 10, а змінній jzm – 20. Потім була викликана функція swap() з адресами змінних izm та jzm. Для отримання адрес тут використовується унарний оператор "&". Отже, функції swap() під час виклику були передані адреси змінних izm та jzm, а не їх значення. Після завершення роботи функції swap() змінні izm та jzm обмінялися своїми значеннями.