Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C лекції / 5.Функц_ї в С.docx
Скачиваний:
36
Добавлен:
05.03.2016
Размер:
53.42 Кб
Скачать

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

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

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

   Прямою (безпосередньою) рекурсією називається рекурсія, при якій всередині тіла деякої функції міститься виклик тієї ж функції.

Типовий приклад використання рекурсії - обчислення факторіала числа ( добутку цілих чисел від одиниці до певного заданого числа). Отже, п! = п(n-1)(n-2)1. Рекурсивна властивість факторіала: n! = п (п-1)!.

Приклад 5. Скласти функцію для обчислення п!, використовуючи рекурсію, можна так:

long factorial (int n)

{

long fact;

if (n > 1) fact = n * factorial(n -1);  else fact = 1;

return fact; }

Зауваження.Оскільки навіть для невеликих чисел значення факторіала є досить великим, то у цьому прикладі для функції factorial задано тип long. Це дає змогу обчислити факторіали чисел від 1 до 16. Для визначення факторіалів чисел більших від 16 необхідно використати алгоритми „довгої арифметики".

 

Приклад 6. Рекурсивна функція обчислення суми цілих чисел від а до має вигляд

int Suma (int a, int b)

{

int S;

if (a == b) S = a;   else S = b + Suma(a, b -1);

return S;

}

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

 

Глобальні та локальні змінні. Операція видимості.

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

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

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

 

#include <iostream.h>

#include<conio.h>

float Max(float,float,float); // Оголошення функції

 

int main()

{

float max,x1,x2,x3;  // Оголошення зиінних

cout << "Введіть три числа ";

cin >> x1 >> x2 >> x3;

max=Max(x1,x2,x3); // Знаходимо max значення серед введених чисел

cout << " Максимальним серед чисел " <<  x1 << ", " << x2 << ", " << x3;

cout << " є "<< max;

system("pause");

return 0;

}

 

float Max(float a,float b,float c)  // Опис функції  Max

{

      float max;

      if (a>b && a>c) max=a;

      else

      if (b>a && b>c) max =b;

      else max=c;

      return max;

}

 

Зауважимо, що у цій програмі змінна max оголошена від­разу у двох функціях main() і Мах().

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

Деяка змінна може бути доступною, але в певний момент невидимою.  Наприклад, якщо глобальна та локальна змінні мають однакове ім'я, то глобальна змінна у області дії відпо­відної локальної змінної буде невидимою. Тобто локальна змін­на  в   області   своєї  визначеності  перекриває  дію  глобальної змінної. Для того, щоб звернутись (доступитись) до глобальної змінної у деякому блоці чи функції, використовують опера­цію надання видимості ::. У цьому випадку до імені змінної зліва дописують два символи двокрапки. Наприклад, ::prybutok, ::day тощо.

 

Класи пам'яті.

Для того, щоб безпосередньо вказати комп'ютеру як і де у його пам'яті мають зберігатися значення змінних чи функцій, як можна отримати доступ до цих даних, як визначити область видимості цих даних, використо­вуютьспецифікатори класу пам'яті. Є п'ять специфікаторів (табл. 1).

 

Таблиця 1. Класи пам'яті

Клас пам'яті

Час дії змінної

Області видимості та дії змінної

auto

Тимчасово

Локальна

register

Тимчасово

Локальна

extern

Тимчасово

Локальна

static

Постійно

Локальна

static

Постійно

Глобальна

volatile

Постійно

Глобальна

 

Розглянемо дії цих специфікаторів.

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

Специфікатор register вказує компілятору, що значення змінної слід зберігати у регістрах. Це зменшує час доступу дозмінної і прискорює виконання програми. Якщо не можливо розмістити змінну у регістрі, то змінна буде збережена зі специфікатором auto. Області дії та видимості регістрових змін­них, як і змінних зі специфікатором auto, обмежені блоком, уякому вони оголошені.

Специфікатор static можна застосовувати як до локальних, так і до глобальних змінних. На відміну від змінних зіспецифікаторами auto чи register значення локальної статичної змінної зберігається після виходу з блока чи функції, де ця змінна оголошена. Під час повторного виклику функції змін­на зберігає своє попереднє значення. Якщо змінна явно не ініціалізована, то за замовчуванням їй надається значення 0.

Приклад 8. Обчислити суму або добуток перших п цілих додатних чисел.

 

// Обчислення суми

#include <iostream.h>

#include <conio.h>

cc (int n);

void main()

{

clrscr();

int n, S;

cout  << "Уведіть число";

сіn  >>  n;

for (int і = 1; і <= n; i++) S = cc(i);

cout << S;

getch();

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

cc(int n)

{ // Цей рядок буде виконано лише один раз

static int S = 0;           // під час першого виклику функції

S +=n;

return S;

}

 

Функція сс призначена для обчислення суми чисел. Якщо cс потрібно обчислити добуток чисел, то фунція таіп() залишиться без змін, а замість функції сс слід записати таку функцію:

cc(int n)

{  static int S = 1;

S*=n;

return S;   }

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

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

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