Смекни!
smekni.com

Розробка програм мовою С++ (стр. 2 из 5)

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

Оголошення функції — це оператор, що включає в себе тип вертаного значення, ім’я функції та її параметри. Цей оператор закінчується крапкою з комою. Мова С++ вимагає, щоб оголошення функції передувало її визначенню або першому використанню в програмі. Таке оголошення називається прототипом функції. Прототип функції вказує компілятору тип даних, що повертаються функцією, кількість параметрів, яку чекає функція, тип параметрів і очікуваний порядок їх слідування. Компілятор використовує прототип функції для перевірки правильності викликів функції. Прототип функції має вигляд:

<тип вертаного значення> <ім’я функції> (<список аргументів>);

Наприклад, int sum (int, int, int);

Цей прототип вказує, що sum має три аргументи типу int і повертає результат типу int.

Прототип розміщується у викличній програмі до заголовку main( ). При наявності прототипу передбачається перетворення аргументів до активізації функції в тип, завданий для відповідно-сті параметрів у прототипі. Наприклад,

int f(float а, float b)

main ( )

{ float a1, int b1;

t = f(a1, b1);

. . . }

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

Прототип функції, розміщений поза описом якоїсь функції, відноситься до всіх викликів даної функції, які виникають після цього прототипу в даному файлі. Прототип функції, розміщений всередині опису певної функції, відноситься лише до викликів усередині цієї функції.

Другим способом оголошення функції перед використанням є поміщення прототипів функцій у заголовний файл (файл з роз-ширенням .h), який підключається директивою #include до тексту програми.

Списки аргументів і параметрів можуть містити невизначену кількість об’єктів. У цьому разі у списку параметрів після останнього ставляться крапки. Якщо у списку параметрів вказані тільки крапки, то список може бути порожнім.

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

Наприклад, визначена користувачем функція sum( ) використовується для розрахунку суми ряду. Ця сума вертається з допо-могою оператора return у функцію main( ) і виводиться на друк.

// Підрахунок суми ряду

#include<iostream.h>

int sum(int, int, int); // прототип функції

main()

{ int nach, kon, shag;

cout << "&bsol;n Введіть початкове значення члена ряду: ";

cin >> nach;

cout << "&bsol;n Введіть кінцеве значення члена ряду: ";

cin >> kon;

cout << "&bsol;n Введіть крок зміни члена ряду: ";

cin >> shag;

cout << "&bsol;n Сума ряду дорівнює " << sum (nach, kon, shag);

return 0;

}

// Визначення функції sum

int sum (int nachr, int konr, int shagr)

{ int i, sumr = 0;

for(i = nachr; i< = konr; i+ = shagr)

sumr+ = i;

return (sumr);

}

1.3 Організація та активація функцій з іеформаційним зв’язком через аргументи і параметри. Передача значень функції

В С++ є три способи передачі аргументів у функцію: передача за значенням, передача за посиланням з аргументами-вказівниками і передача за посиланням з аргументами-посиланнями.

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

У попередньому прикладі функція sum( ) передає копії змінних nach, kon, shagr, які використовуються функцією як значення для параметрів nachr, konr, shagr.

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

1.4 Використання вказівників при роботі з функцією, з даними аргумента і параметрами. Передача вказівників

Щоб мати можливість безпосередньо змінювати значення змінних викличної програми, необхідно використати передачу за посиланням з аргументами-вказівниками. Це, звичайно, необхідне в разі, коли в викличну програму потрібно передавати більше одного значення і повернути більше за одне значення. При цьому передаються не копії змінних, а копії адрес змінних. Функція, використовуючи вказівник, здійснює доступ до потрібних елементів пам’яті, і можна змінювати значення об’єкта, розташовані за цією адресою. Дана передача дозволяє передавати в викличну функцію масиви як аргументи. Якщо масив використовується як аргумент функції, передається тільки адреса масиву, а не копії всіх елементів. При виклику функції з ім’ям масиву в функцію передається вказівник на перший елемент масиву. Існує кілька способів оголошення параметра, призначеного для отримання вказівника на масив.

Перший варіант полягає в тому, щоб використати як аргумент функції ім’я масиву. При передачі масиву в функцію передається також розмірність, щоб функція могла обробляти задане число елементів у масиві. Наявність розмірності індексів в оголошенні параметра повідомляє функцію, як розташовані елементи в масиві. Якщо ми передаємо одновимірний масив як аргумент функції, в списку параметрів функції розмірність може бути опущена, тобто квадратні дужки будуть порожніми. Розмірність першого індексу багатомірного масиву також можна не вказувати, але вся інша розмірність індексів повинна бути зазначена.

Другий спосіб полягає в тому, щоб використати як аргумент функції вказівник на масив.

1.5 Передача за посиланням

В С++ можна здійснювати передачу за посиланням з аргументами-посиланнями. Посилання є неявним вказівником і використовується як інше ім’я вже існуючого об’єкта. Формат визначення посилання є таким:

<тип>& <ім’я посилання> = <вираз; або

<тип>& <ім’я посилання> (<вираз>);

Як вираз, що ініціалізується, має бути ім’я певного об’єкта, що має місце в пам’яті. Значенням посилання після визначення з ініціалізацією стає адреса цього об’єкта. Наприклад,

int х = 7; //Визначена й ініціалізована змінна х

int& ref= х;//Визначене посилання, значенням її є адреса змінної х

Для доступу до вмісту ділянки пам’яті, на який вказує посилання, не треба виконувати розіменування, що є обов’язковим при зверненні до значення змінної через вказівник. Кожна операція над посиланням є операцією над тим об’єктом, з яким вона пов’язана. Можна змінити значення х, записавши х = 35; або ref = 35;.

Існують обмеження при визначенні і використанні посилань:

Не можна взяти адресу змінної типу посилань;

Не можна створити масив посилань;

Не можна створити вказівник на посилання;

Не допускаються посилання на бітові поля.

При використанні посилання як параметра забезпечується доступ із тіла функції до відповідного аргументу, тобто ділянки пам’яті, виділеної для аргументу, тобто початкова змінна може бути змінена за допомогою викличної функції. Щоб указати, що параметр функції передається за посиланням, після типу параметра в прототипі функції записується символ &. У виклику функції змінна вказується на ім’я, але вона буде передана за посиланням.

1.6 Організація та активація функцій з інформаційним зв’язком через зовнішні змінні

Областю дії зовнішніх змінних є всі функції програмного комплексу, якщо ці змінні описані перед якою-небудь функцією, або як extern усередині функції. Це означає, що працювати з зовнішніми змінними можна в межах комплексу і значення, що формуються при цьому, доступні для всіх функцій. У цьому разі немає необхідності здійснювати міжмодульний зв’язок через аргументи і параметри, а достатньо лише активізувати необхідну функцію і продовжити виконання дії з зовнішніми змінними, які були розпочаті в інших функціях. Імена змінних в усіх функціях для позначення відповідних об’єктів повинні обов’язково бути однаковими.

1.7 Рекурсивні функції

Функція називається рекурсивною, якщо вона викликає сама себе. Розрізняють пряму та непряму рекурсії. Функція називається непрямою рекурсивною в тому разі, якщо вона містить звернення до іншої функції, що містить прямий або непрямий виклик першої функції. Якщо в тілі функції явно використовується виклик цієї функції, то має місце пряма рекурсія. Класичним прикладом рекурсії є обчислення факторіала. Факторіал невід’ємного цілого числа n дорівнює

n х (n–1) х (n–2) х. .. х 3 х 2 х 1,


причому за визначенням факторіал 1! і 0! дорівнює 1. Факторіал числа дорівнює добутку попередніх щодо нього послідовностей чисел, тобто n! = nx(n–1)!. Якщо обчислення факторіала оформити у виді рекурсивної функції, то програма може бути подана в ось якому вигляді:

// Обчислення факторіала

#include <iostream.h>

unsigned long factorial (unsigned int);

void main( )

{ int i; unsigned int n;

cout << endl << "Введіть ціле додатне число";

cin >> n;

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

cout << endl << " Факторіал " << i << "!=" << factorial(i);

return;

}

unsigned long factorial (unsigned int num);

{if (n = = 1 ¦¦ n = = 0)

return 1;

else

return (num*factorial(num-1));

}

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