Поняття функції

Функція — це іменована логічно завершена сукупність ого­лошень і операторів, призначених для виконання певної задачі [1, 4-8, 12-14,18, 20].

Програма мовою С++ містить одну або декілька функцій, кожна з яких повинна бути оголошена та визначена до її пер­шого використання. Оголошення функції (прототип, заголовок) задає ім’я функції, тип значення, що повертає функція (якщо воно є), а також імена та типи аргументів, які можуть переда­ватися як у функцію, так і з неї. Визначення функції — це за­дання способу виконання операцій.

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

Усі функції мають однакову структуру визначення у вигляді:

[тип результату] ім'я функції ([список формальних аргументів])

{ // тело функции

опис даних;

оператори;

[return] [вираз];

};

де тип результату — будь-який базовий або раніше описаний тип значення (за винятком масиву і функції), що повертається функцією (необов’язковий параметр). За відсутності цього па­раметра тип результату за замовчуванням буде цілий (int). Він також може бути описаний ключовим словом (void), тоді функ­ція не повертає ніякого значення. Якщо результат повертаєть­ся функцією, то в тілі функції є необхідним оператор return вираз;, де вираз формує значення, що співпадає з типом ре­зультату;

 ім’я функції — ідентифікатор функції, за яким завжди знахо­диться пара круглих дужок «( )», де записуються формальні ар­гументи. Фактично ім’я функції — це особливий вид покажчика на функцію, його значенням є адреса початку входу у функцію;

список формальних аргументів — визначає кількість, тип і порядок проходження переданих у функцію вхідних аргумен­тів, які розділяються комою («). У випадку, коли параметри відсутні, дужки залишаються порожніми або містять ключове слово (void). Формальні параметри функції локалізовані в ній і недоступні для будь-яких інших функцій.

Список формальних аргументів має такий вигляд:

([const] тип 1 [параметр 1], [const] тип 2 [параметр 2], . . .)

У списку формальних аргументів для кожного парамет­ра треба вказати його тип (не можна групувати параметри одного типу, вказавши їх тип один раз).

Тіло функції може складатися з описів змінних і операто­рів. Змінні, що використовуються при виконанні функції, мо­жуть бути глобальні і локальні. Змінні, що описані (визначені) за межами функції, називають глобальними. За допомогою глобальних параметрів можна передавати дані у функцію, не включаючи ці змінні до складу формальних параметрів. У тілі функції їх можна змінювати і потім отримані значення пере­давати в інші функції.

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

static int

х, у;

або static float р = 3.25;.

 

Статична змінна схожа на глобальну, але діє тільки у тій функції, в якій вона оголошена.

На початку програми можна не описувати всю функцію, а записати тільки прототип. Запис прототипу може містити тіль­ки перелік типів формальних параметрів без імен, а наприкін­ці прототипу завжди ставиться символ “;», тоді як у описі (ви­значенні) функції цей символ після заголовка не присутній.

Механізм передачі параметрів є основним засобом обміну ін­формацією між функцією, що викликається, та функцією, яка викликає. Параметри, котрі зазначаються у заголовку опису функції, як відомо, називаються формальними, а параметри, які записані у операторах виклику функції — фактичними. Наведе­мо приклад фрагмента програми з використанням функцій:

double sqr (double

); //-------------- прототип функции sqr()

main( ) //------------------ главная функция

{ //---------------- вызов функции sqr()

cout << "Квадрат числа=" << sqr (10) << endl;

}

double sqr (double p) //---------------------- функция sqr()

{ return p*p; } //-------------- возврат no значению

 

У результаті виконання програми буде виведено:

Квадрат числа = 100

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

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

У мові С++ визначено декілька способів передачі парамет­рів і повернення результату обчислень функцій, серед них най­більш широке використання набули:

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

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

void fun (int

р) //----------- функция fun()

{++p;

cout << " p = " << p << endl; }

void main ( ) //----------- главная функция

{ int x = 10;

fun (x); //----------- вызов функции

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

 

Результат роботи цього фрагмента програми:
р=11, х=10,

оскільки для виклику функції fun(x) до неї передається копія значення, що дорівнює 10. Всередині функції значення копії змінної збільшується на 1, тобто (++р), і тому виводиться

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

При цьому способі для звертання до функції достатньо на­писати її ім’я, а в дужках — значення або перелік фактичних аргументів. Фактичні аргументи повинні бути записані в тій же послідовності, що і формальні, і мати відповідний тип (крім аргументів за замовчуванням і перевантажених функцій).

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

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

// Р9_1.СРР — использование функции поддержки русского шрифта

#include <iostream.h>

#include <conio.h>

const int n=100;

//------------------------------- функция поддержки русского шрифта

char *rus(char *text)

{ for (int і = 0; і < strlen(text); i++)

  if (text >= 'A' && text[i] <= 'n')

  text[i] = char(int(text[i]-64));

  else

  if (text[i] >= 'р' && text[i] <= 'я')

  text[i] = char(int(text[i]-16)); return text;

}

//-------------------------------------------------------- главная функция

void main() {

char s[100];

cout << rus("введите строку на русском языке")<<endl;

cin.getline(s,sizeof(s));

cout << s;

getch();

}

Слід зауважити, що середовище С++ Builder та деякі інші середовища не підтримують російську символіку, і тому повідомлення російською мовою при потоковому виведенні «cout<<» представляються на екрані у вигляді псевдокодів. Так, підказка в операторі

cout <<“введите строку на русском языке”<<еndl;

при виконанні програми матиме такий вигляд:

ааШ6& Шіеб їй ббййШ

Застосування розробленої функції rus(char *text) дозволить на етапі виконання програми вивести російський текст без змін, тобто:

введите строку на русском языке .

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

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

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

// использование параметра-указателя

void fun

2 (int *p)

{ ++*p;

cout << "*p = " << *p << endl; }

void main ( )

{ int x = 10;

fun2 (&x); // вызов функции

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

}

 

У результаті буде виведена інформація:

*p = 11 і x = 11 .

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

Наприклад:

//-------------- использование параметра-ссылки

void fun (int &p) //---------- функция fun()

{ ++p;

cout << "p = " << p << endl; }

void main ( )

{ int x = 10;

fun (x); //---------- вызов функции fun()

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

}

Одержимо результат попереднього фрагмента, тобто

р = 11 і х=11.

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

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

#include

< iostream.h >

int a, b, с;             // глобальные параметры

sum ( );                 //----------- прототип функции

main ( )                //----------- главная функция

{ cin >> а >>b;

sum();                //----------- вызов sum()

cout << с << endl;

}

sum( )                   //----------- функция sum()

{ с = а + b; }

 

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

В останніх версіях мови С++ з’явилася можливість переда­вати дані за замовчуванням. У цьому випадку при написанні функції всім аргументам або декільком з них присвоюються початкові значення і задовольняються такі вимоги: коли якому-небудь аргументу присвоєно значення за замовчуванням, то всі аргументи, що розташовані за ним (тобто записані право­руч), повинні мати значення за замовчуванням. Таким чином, список параметрів поділяється на дві частини: параметри, що не мають значення за замовчуванням, і параметри, що мають такі значення.

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

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

void functl (float х, int у, int z = 80)

{ cout << "x = " << x << " у = " << у << "z = " << z << endl; }

void funct2 (float x, int у = 25, int z = 100)

{ cout << "x = " << x << "y = " << у << "z = " << z << endl; }

void funct3 (float x = 3.5, int у = 40, int z = 200)

{ cout << "x = " << x << "y = " << у << "z = " << z << endl; }

main ( ) {

functl (5.1, 10); //пo умолчанию передаётся один аргумент — z 

funct2 (10.2); //пo умолчанию передаются два аргумента — у, z

funct3 ( );         // по умолчанию передаются все аргументы

}

На екрані буде виведено:

х = 5.1       у = 10      z = 80

х = 10.2    у = 25      z = 100

х = 3.5      у = 40      z = 200

З цієї ілюстраційної програми видно, що аргумент за замов­чуванням — це той аргумент, значення якого задане при описі заголовка функції, а при її виклику його можна не вказувати.

Якщо замість параметра, заданого за замовчуванням при звертанні до функції, записується інше значення фактичного параметра, то значення за замовчуванням перекривається заданим фактичним значенням. Так, наприклад, в останньому програм­ному фрагменті при виклику функції functl (13.5, 75); на ек­рані буде виведено:

х = 13.5        у = 75       z = 80,

тобто z — прийнято за замовчуванням.

Приклад 9.2. Обчислити квадратну функцію вигляду у = ах2 + Ьх + с для заданого значення аргументу х з використанням функції, у яку коефіцієнти a, b і с можуть бути введені за замовчуванням.

// P9_2.CPP — вычисление квадратной функции y = axl +bx + c /* коэффициентыa, b и с вводятся в функцию по умолчанию */

#include <iostream.h>

#include <conio.h>

float ur (float х, float а = 0., float b = 0., float с = 0.);

int main ( )

{

float a =1., b = 2., с = 3., x = 0.5, y;

cout << "\n***** Введены все аргументы " << endl;

y = ur (x, а, b, с); //-------------- вызов функции ur()

cout << " у = "<< у << endl;

cout << "\n***** Введены аргументы x, a, b " << endl;

у = ur (x, a, b);

cout << " у = "<< у << endl;

cout << "\y***** Введен аргумент x " << endl;

у = ur (x);

cout << " у = "<< у << endl;

getch ();                                  // задержка экрана

}

//--------------- функция вычисление квадратной зависимости

float ur (float х, float a, float b, float с) 

{

return a*x*x + b*x + c;

}

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

***** Введены все аргументы

у = 4.25

***** Введен аргумент х

у = 0

***** Введены аргументы  х, a, b

у = 1.25

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

static char st[ ] = “Гакк М.Ю.”;.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *