
- •1 Основні елементи мови с
- •1.1 Алфавіт мови програмування
- •1.2 Лексеми
- •1.3 Ключові слова
- •1.4 Ідентифікатори
- •1.5 Класифікація типів даних
- •1.6 Літерали
- •1.7 Оператори
- •1.8 Коментарі
- •1.9 Директиви препроцесора
- •1.10 Організація програми
- •2 Операції та вирази
- •2.1 Загальні відомості
- •2.2 Арифметичні операції
- •2.3 Операції приведення типів
- •2.4 Операції присвоєння
- •2.5 Операції інкремента і декремента
- •2.6 Операції порівняння
- •2.7 Операції зсуву
- •2.8 Порозрядні операції
- •2.9 Логічні операції
- •2.10 Операція sizeof
- •2.11 Операція послідовного обчислення
- •2.12 Операція умови (?:)
- •2.13 Адресні операції
- •3 Прості типи даних
- •3.1 Оголошення змінних
- •3.2 Час існування та область видимості змінних
- •3.3 Цілі типи даних
- •3.4 Дійсні типи даних
- •4 Оператори керування
- •4.1 Оператор розгалуження if
- •4.2 Оператор розгалуження if-else
- •4.3 Оператор множинного розгалуження switch
- •4.4 Оператор циклу for
- •4.5 Оператор циклу while
- •4.6 Оператор циклу do while
- •4.7 Оператор break
- •4.8 Оператор continue
- •5 Функції
- •5.1 Основні поняття
- •5.2 Види виклику функцій
- •5.3 Область видимості
- •5.4 Порожній тип void
- •5.5 Передача аргументів у функцію
- •5.6 Рекурсивні функції
- •5.7 Прототипи функцій
- •6 Покажчики
- •6.1 Визначення та ініціалізація покажчиків
- •6.2 Визначення покажчиків
- •6.3 Масиви
- •6.4 Операції порівняння
- •6.5 Копіювання рядка
- •6.6 Покажчики на функцію
- •6.7 Покажчики на void
- •6.8 Арифметика покажчиків
- •7 Масиви
- •7.1 Загальні поняття
- •7.2 Одновимірні масиви
- •7.3 Багатовимірні масиви
- •8 Рядки в с
- •8.1 Рядки
- •8.2.Створення рядків
- •8.3 Прототипи
- •8.3 Функції перетворення буферів
- •8.4 Функції перевірки літер
- •8.5 Операції з рядками
- •9 Структури, об’єднання, перерахування
- •9.1 Структури
- •9.2 Бітові поля
- •9.3 Ключове слово typedef
- •9.4 Об’єднання
- •9.5 Перераховуваний тип
- •10 Введення та виведення даних
- •10.1 Функція виведення printf
- •10.2Функція введення scanf
- •10.3 Введення та виведення у файл
- •11 Динамічне виділення пам'яті
5.6 Рекурсивні функції
Рекурсивна функція – це функція, яка викликає саму себе. За допомогою рекурсії легко вирішуються такі завдання як сортування або обчислення факторіала числа.
Факторіал цілого невід'ємного числа n, записується як n!, і обчислюється за формулою:
n! = n * (n-1) * (n-2) * (n-3) * ... * 1
Наприклад, факторіал п'яти, є добутком 5*4*3*2*1, який дорівнює 120.
Розглянемо рекурсивну функцію для обчислення факторіалу:
Приклад 5.5 Обчислення факторіалу.
#include <stdio.h>
#include <stdlib.h>
int fact(int a)
{
if (a > 1)
return (a * fact(a – 1));
else
return(1);
}
int main ()
{
int n;
printf("Vvedit chuslo: ");
scanf ("%i",&n);
printf("%i! = %i \n", n, fact(n));
system("PAUSE");
return 0;
}
Результат роботи програми:
Функція fact викликатиме сама себе, постійно зменшуючи аргумент наступного виклику на 1 до тих пір, поки аргумент не стане рівний 1. В цьому випадку функція поверне число 1 (рис 5.4).
Рисунок 5.4 – Приклад обчислення 5! за допомогою рекурсивної функції.
5.7 Прототипи функцій
Прототип функції – це оголошення функції, яке не містить тіло функції і повідомляє компілятору:
тип даних, який повертає функція;
число, тип та порядок параметрів, які функція приймає.
Прототип дає можливість викликати функцію до моменту її оголошення.
Прототипи функцій використовуються для перевірки коректності виклику функцій. У випадку не узгодження прототипу функції та її визначення виникає помилка на етапі компіляції.
Синтаксис оголошення прототипу функції наступний:
<тип> <ім’я функції> (параметр1, параметр2,…);
Цей синтаксис ідентичний визначенню функції, за винятком того що він не включає тіло самої функції, а в кінці ставиться крапка з комою (;).
Компілятор ігнорує імена змінних вказаних в прототипі функції, тобто при оголошенні прототипу достатньо вказати лише типи параметрів.
Приклад 5.6. Використання прототипу функції без вказання імен змінних у прототипі.
#include <stdio.h>
int function(int, int, int); /* оголошення прототипу
функції*/
int main(void) /* головна програма*/
{
printf ("suma = %d \n", function (4, 5, 6));
return 0;
}
int function(int a, int b, int c) /* визначення функції*/
{
return a + b + c;
}
Приклад 5.7. Використання прототипів функцій.
#include <stdio.h>
#include <stdlib.h>
void Parne(int a); /* оголошення прототипу
функції Parne*/
void Neparne(int a); /* голошення прототипу
функції Neparne*/
int main ()
{
int i;
printf(" Vvedit chuslo(Vuhid – 0): ");
scanf ("%i",& i);
while (i!=0) {
Parne(i);
printf(" Vvedit chuslo(Vuhid – 0): ");
scanf ("%i",& i);
}
system("PAUSE");
return 0;
}
void Parne (int a) /*визначення функції Parne*/
{
if ((a%2)==0)
printf("Parne.\n ");
else Neparne(a);
}
void Neparne (int a) /* визначення функції Neparne*/
{
if ((a%2)!=0)
printf("Neparne.\n ");
else Parne(a);
}
Результат роботи програми:
У прикладі 5.7 показано випадок у якому необхідно використовувати прототипи функцій.
На початку програми оголошуються прототипи функцій Parne і Neparne:
void Parne (int a);
void Neparne (int a);
Прототипи дозволяють викликати функції до моменту їх визначення. На рисунку 5.5 зображено структури програм з використанням прототипу функції та без нього.
Рисунок 5.5 – Cтруктура програми з прототипом функції та без нього
У програмі з прикладу 5.7 неможливо обійтись без прототипів, так як існує потреба взаємного викли5ку двох функцій (функція Parne викликає функцію Neparne, яка в свою чергу викливає функцію Parne). Якщо не використовувати прототипи, то компілятор видаватиме помилку, так як функція описана в програмі першою, викликатиме функцію, яка не описувалась в програмі раніше.
Контрольні запитання
Для чого потрібні функції?
Опишіть синтаксис визначення функції.
Чим відрізняється аргумент і параметр функції?
Що таке область видимості змінних?
Що таке локальна змінна?
Опишіть декілька видів виклику функцій.
Що таке тип функції?
Коли і для чого використовується тип void?
Назвіть два види передачі параметрів у функцію.
Що таке передача параметрів за посиланням?
Для чого потрібна передача параметрів за посиланням
Для чого потрібні рекурсивні функції?
Назвіть основні переваги та недоліки рекурсивних функцій.
Для чого використовуються прототипи функцій?
В яких випадках неможливо обійтись без прототипів функцій?
Опишіть синтаксис оголошення прототипу функції.
Напишіть програму, яка зчитуватиме з клавіатури 2 числа і в залежності від введеного числа 1, 2, 3 чи 4 виводитиме на екран їх суму, різницю, добуток чи частку відповідно.