русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Взаємодія фактичних і формальних параметрів функцій


Дата додавання: 2014-04-22; переглядів: 2218.


Коли відбувається звертання до функції, всі її формальні параметри отримують значення відповідних фактичних параметрів, заданих у виклику цієї функції. Тому кількість фактичних параметрів повинна строго відповідати кількості формальних параметрів. Фактичні параметри можуть бути довільними виразами, але тип значення кожного з них має бути сумісним з типом відповідного формального параметра, тобто значення виразу може бути перетворене до типу формального параметру.

Механізм взаємодії формальних і фактичних параметрів при виклику і виконанні функції такий:

1) послідовно обчислюються значення виразів, записаних у виклику функції, тобто значення її фактичних параметрів;

2) значення кожного з фактичних параметрів перетворюється до типу відповідного формального параметру, перетворення виконується згідно з правилами узгодження типів в операціях присвоєння;

3) для кожного формального параметру функції створюється змінна, якій присвоюється значення відповідного фактичного параметру;

4) ці змінні використовуються всередині функції при її роботі;

5) після завершення роботи функції пам’ять, яку було виділено для параметрів і внутрішніх змінних функції, звільняється.

Таким чином, в тілі функції опрацьовуються копії значень фактичних параметрів, значення самих фактичних параметрів при цьому не змінюються. Це важливий момент, який обов’язково необхідно враховувати при створенні функцій. Наступна функція повертає найбільше з трьох цілих чисел:

 

#include <iostream>

using namespace std;

int max( int a, int b, int c ) { // Формальні параметри

a = a > b ? a : b;

return a > c ? a : c;

}

int main() {

int x = 3, m;

m = max( х, 2, x + 1 ); // Фактичні параметри

cout << m << endl;

}

 

Формальні параметри в цьому прикладі – це змінні a, b, c, фактичні параметри – це значення 2, х, х+1. При звертанні до функції змінна а отримає значення змінної х, змінна b – значення 2, змінна c – значення виразу х+1. Всередині функції значення змінної а змінюється, але це не вплине на значення відповідного фактичного параметра, тобто х. Такий взаємозв’язок параметрів називається звертанням за значенням (call by value).

Зразком неправильного звертання за значенням параметрів може бути наступна функція, яка має міняти місцями значення двох змінних:

 

#include <iostream>

using namespace std;

void swap( int a, int b ) {

int t = a;

a = b;

b = t;

}

int main() {

int x = 3, y = 4;

swap( x, y );

cout << "x = " << x << endl;

cout << "y = " << y << endl;

}

 

Всередині функції значеннями будуть обмінюватися формальні параметри (a i b), які існують в пам'яті тільки під час існування функції. Значення фактичних параметрів, тобто значення змінних х і у, не змінюються.

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

Для того, щоб функція swap почала правильно працювати, необхідно передавати в цю функцію адреси змінних, тобто формальні параметри функцій мають бути вказівниками на змінні, значення яких переставляються:

 

void swap( int * a, int * b ) {

int t = *a;

*a = *b;

*b = t;

}

 

Створимо програму, яка буде переставляти елементи масиву в зворотному порядку. Функції для роботи з масивами запишемо в окремому заголовному файлі.

 

// array.h --------------------------------------------------------

#ifndef ARRAY_H

#define ARRAY_H

#include <iostream>

#include <ctime>

using namespace std;

//-----------------------------------------------------------------

void array_fill( int * p, int n ) {

srand( unsigned( time ( NULL ) ) );

for ( int i = 0; i < n; i++ )

p[ i ] = rand( ) % 100;

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

void array_print( int * p, int n ) {

for ( int i = 0; i < n; i++ )

cout << p[ i ] << "\t";

cout << endl;

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

void array_swap( int * a, int * b ) {

int t = *a;

*a = *b;

*b = t;

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

void array_reverse( int * p, int n ) {

for ( int i = 0; i < n / 2; i++ )

array_swap( &p[ i ], &p[ n - 1 - i ] );

}

#endif

 

#include "array.h"

#include <iostream>

using namespace std;

int main() {

const int NUM = 5;

int a[ NUM ];

array_fill( a, NUM );

array_print( a, NUM );

array_reverse( a, NUM );

array_print( a, NUM );

}

 

Функція main містить тільки оголошення констант, змінних і виклики функцій. Описи функцій зберігаються в файлі array.h, який можна підключати до будь-якого проекту.


<== попередня лекція | наступна лекція ==>
Виклик функцій. Прототипи функцій | Inline – функції


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн