Опис та використання функцій

Содержание

Слайд 2

Навчальні питання

(с) Гроза П.М.

Створення й використання функцій
Аргументи функції
Рекурсивні функції

Навчальні питання (с) Гроза П.М. Створення й використання функцій Аргументи функції Рекурсивні функції

Слайд 3

Керниган Б., Ритчи Д. Язык программирования Си ДПер. с англ., 3-е изд.,

Керниган Б., Ритчи Д. Язык программирования Си ДПер. с англ., 3-е изд.,
испр. — СПб.: "Невский Диалект", 2001. - 352 с: ил.
Язык програмирования С++. Лекция и упражнения. Учебник: Перевод с анг./Стивен Прата – СПб.: ООО «ДиаСофтЮП», 2005.-1104с.
Теренс Чан Системное програмирование на С++ для UNIX: пер. с англ. – К.: Издательская группа ВНV, 1997. – 592с.
Уэйк М., Прата С., Мартин Д. Язык Си Руководство для начинающих: Пер. с англ.. – М: Мир, 1988.-512с.,ил.

Література

(с) Гроза П.М.

Слайд 4

(с) Гроза П.М.

1. Створення й використання функцій

(с) Гроза П.М. 1. Створення й використання функцій

Слайд 5

Типові етапи рішення задач (підзадачі)

(с) Гроза П.М.

Типові етапи рішення задач (підзадачі) (с) Гроза П.М.

Слайд 6

модуль, що містить деяку послідовність операцій
Процес розробки та реалізації – це побудова

модуль, що містить деяку послідовність операцій Процес розробки та реалізації – це
операцій, що вирішують конкретну задачу
Розроблена функція
Окрема абстрактна операція
Для використання необхідно знати інтерфейс функції
вхідні дані
результати виконання

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

(с) Гроза П.М.

Слайд 7

Функції мови Сі
printf( ), scanf( ), getchar( ), putchar( )
Створена функція

Функції мови Сі printf( ), scanf( ), getchar( ), putchar( ) Створена

main( )

Приклади функцій

(с) Гроза П.М.

Слайд 8

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

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

Використання функції забезпечує

(с) Гроза П.М.

Слайд 9

!!! Вміст (код) “чорного ящика” при використанні програміста не цікавить
Програміст має знати

!!! Вміст (код) “чорного ящика” при використанні програміста не цікавить Програміст має
інтерфейс функції
формат вхідної інформації
формат повертаємих результатів
Інтерфейс описується в прототипі функції

Відношення програміста до функцій -“Чорний ящик”

(с) Гроза П.М.

Слайд 10

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

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

Вхідні та вихідні дані функції

(с) Гроза П.М.

Слайд 11

– послідовність операторів над аргументами або змінними функції відповідного типу даних
Змінні що

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

Код функції

(с) Гроза П.М.

Слайд 12

тип_поверт_значення ім’я_функції ([параметри])
{
тіло функції
}
ім'я функції - правильний ідентифікатор
тіло

тип_поверт_значення ім’я_функції ([параметри]) { тіло функції } ім'я функції - правильний ідентифікатор
функції
визначення й описи змінних
оператори
параметри – аргументи функції
тип_поверт_значення - в мові С є не обов'язковим

Синтаксис опису функції

(с) Гроза П.М.

Рис. 9.1

Слайд 13

/* Обрахування квадрату х, опис функції в програмі */
float qvdr (float x)

/* Обрахування квадрату х, опис функції в програмі */ float qvdr (float
{
return x*x;
}

Приклад

(с) Гроза П.М.

Слайд 14

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

Вимагає, щоб визначення функції включило в себе формальний аргумент того ж типу,
що й фактичний
Опис
void function1(int ); //опис прототипу функції, поміщаємо до файлу опису
void function2(int *); //опис прототипу функції, поміщаємо до файлу опису
int x=10; //в тілі головної функції
Передача значення змінної х
function1(x); //в тілі головної функції
Передача адреси змінної x
function2(&x); //в тілі головної функції

Передача фактичного аргументу у функцію

(с) Гроза П.М.

Слайд 15

Виконано весь код тіла функції
Зустрівся оператор return

Завершення виконання функції

(с) Гроза П.М.

Виконано весь код тіла функції Зустрівся оператор return Завершення виконання функції (с) Гроза П.М.

Слайд 16

значення
покажчик на масив
покажчик на функцію
Тип void - функція не має повертаємого

значення покажчик на масив покажчик на функцію Тип void - функція не
значення
Тіло функції при повернені значення х завершується оператором
return (х);
!!! Функція не може повертати масив або функцію

Функція повертає

(с) Гроза П.М.

Слайд 17

Завершує виконання коду функції
Повертає результат роботи функції в основну програму
Передає управління в

Завершує виконання коду функції Повертає результат роботи функції в основну програму Передає
основній програмі, наступному операторові який знаходиться за викликом функції
!!! Завершення коду відбувається навіть у тому випадку, якщо оператор return є не останнім оператором у функції
main( )
{
int a=10;
d=abs(a);
return; /* повертаєме значення відсутнє */
}
/* Функція, що обчислює абсолютну величину числа*/
abs(int x) {
if(x < 0) return(-x);
else return(x);
printf("Робота завершена!\n");
}

Оператор return

(с) Гроза П.М.

Слайд 18

Оголошенню функції можуть передувати специфікатори класу пам’яті extern або static
static обмежує видимість

Оголошенню функції можуть передувати специфікатори класу пам’яті extern або static static обмежує
функції - невидима поза утримуючим її файлом
Якщо в описі не зазначений клас пам'яті - замовчуванням extern
В середині функцій можливий виклик будь-якої іншої функцій
!!! Неможливо оголосити функцію в середині тіла іншої функції
!!! Якщо в програмі є звертання до функції - опис прототипу функції має розміщатися раніше її визначення і звернення

Оголошення функцій

(с) Гроза П.М.

Слайд 19

#include
/* прототипу функції func1( ), func2( ) рекомендується розмістити до файлу заголовку,

#include /* прототипу функції func1( ), func2( ) рекомендується розмістити до файлу
приклад File10.h , а файл включити #include "File10.h " */
float func2(float , float );
void func1(char *);
/* головна програма */
main() {
int a=4, b=5;
func1(“a*b= ");
printf(" %f", func2(a, b));
return 0;
}
/* визначення функцій func1( ) */
void func1(char *sh) {
printf("%s", sh);
}
float func2(float x, float y) {
return x*y;
}

(с) Гроза П.М.

Приклад

Слайд 20

/*Головна програма в Union10.c, до проекту необхідно включити всі перераховані файли */

/*Головна програма в Union10.c, до проекту необхідно включити всі перераховані файли */

#include
#include "File10.h "
main()
{
float a=4, b=5;
func1(“a*b= ");
printf(" %d", func2(a, b));
return 0;
}
/* File10.с - файл визначення функцій func1( ), func2( ) */
void func1(char *sh)
{
printf("%s", sh);
}
float func2(float x, float y)
{
return x*y;
}
/* File10.h - файл оголошення прототипу функцій func1( ), func2( ) */
void func1(char *);
float func2(float, float );

Приклад – рекомендуєма структура

(с) Гроза П.М.

Слайд 21

Питання

(с) Гроза П.М.

Питання (с) Гроза П.М.

Слайд 22

2. Аргументи функції

(с) Гроза П.М.

2. Аргументи функції (с) Гроза П.М.

Слайд 23

Формальний аргумент - змінна у визначенні (заголовку) функції
Фактичний аргумент - конкретне значення,

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

Аргумент

(с) Гроза П.М.

Слайд 24

/*Головна програма Union10.c, до проекту необхідно включити всі перераховані файли */
#include

/*Головна програма Union10.c, до проекту необхідно включити всі перераховані файли */ #include
#include "File10.h”
main()
{
float a=4, b=5;
func1(“a*b= ");
printf(" %d", func2(a, b)); /*фактичні аргументи а,b*/
return 0;
}
/* File10.с - файл визначення функцій func1( ), func2( ) */
void func1(char *sh) /* формальні аргументи *sh */
{
printf("%s", sh);
}
float func2(float x, float y) /* формальні аргументи х, у*/
{
return x*y;
}
/* File10.h - файл оголошення прототипу функцій func1( ), func2( ) */
void func1(char *); /*прототип – визначає тип формального аргументу *sh */
float func2(float, float );

Приклад

(с) Гроза П.М.

Слайд 25

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

виділення ділянки пам'яті для формальних параметрів обчислення значення фактичних параметри при виклику
значення фактичних параметрів в ділянки пам'яті, що виділені для формальних параметрів
виконання коду у тілі функції з використанням значень отриманих та внутрішніх об'єкт-параметрів
передача результатів в точку виклику функції
!!! Функція не має впливу на фактичні параметри головної

Робота компілятора при роботі з функцією

(с) Гроза П.М.

Слайд 26

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

Явні аргументи Список специфікації аргументів, кількість і типи яких фіксовані та відомі
в момент компіляції
Змінна кількість аргументів
Має один або кілька обов'язкових аргументів
Інші аргументи не визначені на момент компіляції

Специфікації аргументів

(с) Гроза П.М.

Слайд 27

Усі параметри, за винятком параметрів типу покажчик передаються за значенням
При виклику
у функцію

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

Передача аргументів за значенням

(с) Гроза П.М.

Слайд 28

 /*Вивід значення та адреси аргументу функції в основній програмі та в тілі

/*Вивід значення та адреси аргументу функції в основній програмі та в тілі
функції*/
#include
void main( ) {
int a=10;
printf("before test : a=%d, &a=%u \n", a, &a );
test(a);
printf("after test : a=%d, &a=%u \n", a, &a );
return;
}
/* Test1.с */
void test(int a) {
a=15;
printf(“ in function test1: a=%d, &a=%u \n", a, &a );
}
/* Test1.h */
void test(int );
Результат
before test : a=10, &a=55990
in function test1: a=15, &a=55994
after test : a=10, &a=55990

Приклад передачі аргументу за значенням

(с) Гроза П.М.

Слайд 29

При виклику функції
відводиться пам’ять для локальних копій параметрів → призводить до

При виклику функції відводиться пам’ять для локальних копій параметрів → призводить до
збільшення об’єму задіяної пам’яті
копіюється в неї фактичний параметр → затрачається час на копіювання
При виході з функції - пам’ять звільняється

Особливість передачі аргументу за значенням

(с) Гроза П.М.

Рис. 9.2

Слайд 30

Додатково об’єми пам'яті під формальні змінні не створюються → не витрачається додатковий

Додатково об’єми пам'яті під формальні змінні не створюються → не витрачається додатковий
час для копіювання даних в пам'яті

Передача аргументів за покажчиком

(с) Гроза П.М.

Рис. 9.3

Слайд 31

 /*Вивід значення та адреси аргументу функції в основній програмі та в тілі

/*Вивід значення та адреси аргументу функції в основній програмі та в тілі
функції*/
#include
void main( ) {
int a=10;
printf("before test : a=%d, &a=%u \n", a, &a );
test(&a);
printf("after test : a=%d, &a=%u \n", a, &a );
return;
}
/* Test1.с */
void test(int *a) {
*a=15;
printf(“ in function test1: a=%d, &a=%u \n", *a, a );
}
/* Test1.h */
void test(int *);
Результат
before test : a=10, &a=55990
in function test1: a=15, &a=55990
after test : a=15, &a=55990

Приклад передачі аргументу за показником

(с) Гроза П.М.

Слайд 32

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

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

Опис
тип ім’я_функції(список аргументів, ...)
Список аргументів включає
скінченне число обов’язкових параметрів - список не може бути порожнім
невизначене число аргументів - ставиться три крапки

Функції із змінним числом аргументів

(с) Гроза П.М.

Слайд 33

У stdarg.h визначений тип списку va_list і три функції
va_start( ), va_arg(

У stdarg.h визначений тип списку va_list і три функції va_start( ), va_arg(
), va_end( )
Функція va_start( ) - починає роботу зі списком і встановлює покажчик ap на перший аргумент списку аргументів з невизначеним числом
Синтаксис void va_start(va_list ap, lastfix)
lastfix – ім'я останнього фіксованого параметру
Функція va_arg() - повертає значення наступного аргументу зі списку
Синтаксис void va_arg(va_list ap, type)
Перед викликом va_arg( ) значення ap повинне бути встановлене викликом va_start( ) або va_arg( )
Кожний виклик va_arg( ) переводить покажчик на наступний аргумент
Функція va_end() - завершує роботу зі списком, звільняючи пам’ять
Синтаксис void va_end(va_list ap)

Робота зі змінним числом аргументів

(с) Гроза П.М.

Слайд 34

//Функція сумує аргумкети, признак кінця списку аргументів - 0
#include
#include

//Функція сумує аргумкети, признак кінця списку аргументів - 0 #include #include #include

#include "Test3.h“
int main(void)
{
sum("Сума 1+2+3+4 рівна %d\n", 1,2,3,4,0);
return 0;
}
/* Файл Test3.c */
void sum(char *msg, ...)
{
int total = 0;
va_list ap;
int arg;
va_start(ap, msg);
while ((arg = va_arg(ap, int)) != 0) total += arg;
printf(msg, total);
va_end(ap);
}
/* Файл Test3.h* /
void sum(char * , ...) ;

Приклад

(с) Гроза П.М.

Слайд 35

Питання

(с) Гроза П.М.

Питання (с) Гроза П.М.

Слайд 36

(с) Гроза П.М.

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

(с) Гроза П.М. 3. Рекурсивні функції

Слайд 37

Визначення

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

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

(с) Гроза П.М.

Слайд 38

Пряма рекурсія

рекурсія, при якій всередині тіла деякої функції міститься виклик тієї ж

Пряма рекурсія рекурсія, при якій всередині тіла деякої функції міститься виклик тієї
функції
При виклику
в стеку створюється копія значень її параметрів, як і при виклику звичайної функції
після чого управління передається першому оператору функції
При повторному виклику цей процес повторюється
void funk(int i)
{
/* ... */
funk (i);
/* ... */
}

(с) Гроза П.М.

Слайд 39

Непряма рекурсія

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

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

(с) Гроза П.М.

Рис. 9.4

Слайд 40

Приклад непрямої рекурсії

void fnA(int i);
void fnB(int i);
void fnC(int i);
void fnA(int

Приклад непрямої рекурсії void fnA(int i); void fnB(int i); void fnC(int i);
i) {
/* ... */
fnB (i);
/* ... */
}
void fnB(int i) {
/* ... */
fnС(i);
/* ... */
}
void fnC(int i) {
/* ... */
fnA(i);
/* ... */
}

(с) Гроза П.М.

Слайд 41

Приклад рекурсивно обчислює n!

/*зручно скористатися рекурсивним виразом n!=n*(n-1)! при n=6, n!= ?*/
#include

Приклад рекурсивно обчислює n! /*зручно скористатися рекурсивним виразом n!=n*(n-1)! при n=6, n!=

#include
double fact(int n) {
if (n<=1) return 1;
return (fact(n-1)*n);
}
void main()
{
int n;
double value;
clrscr();
printf("N=");
scanf("%d",&n);
value=fact(n);
printf("%d! = %.50g",n,value);
getch();
}
У файлі прототипу опис double fact(int) ;

(с) Гроза П.М.

Слайд 42

Кроки при розробці рекурсивних функцій

1) Рекурсивне занурення функції в саму себе -

Кроки при розробці рекурсивних функцій 1) Рекурсивне занурення функції в саму себе
поки вибраний параметр не досягне граничного значення
Важлива вимога, щоб функція не створила нескінченну послідовність викликів самої себе
Глибина рекурсії - кількість кроків
2) Рекурсивний вихід - поки вибраний параметр не досягне початкового значення
Забезпечує отримання проміжних і кінцевих результатів

(с) Гроза П.М.

Слайд 43

Покажчики на функції

використовується для передачі функцій як параметрів іншим функціям
За означенням покажчик

Покажчики на функції використовується для передачі функцій як параметрів іншим функціям За
на функцію містить адресу першого байта або слова виконуваного коду функції
/* покажчик на функцію, що приймає два параметри типу float і повертає значення типу float */
float (*func) (float a, float b);

(с) Гроза П.М.

Слайд 44

Особливість використання покажчика на функцію

Для використання покажчика на функцію потрібно спочатку

Особливість використання покажчика на функцію Для використання покажчика на функцію потрібно спочатку
присвоїти йому значення адреси пам’яті, де розташована функція
Приклад - помилка використання
#include
#include
void main(void)
{
void (*efct)(char *s); /* змінній-покажчику виділена ОП, але efct не містить значення адреси ОП для функції */
efct("Error"); /* груба помилка – спроба працювати з неініціалізованим покажчиком*/
}
!!! Не путайте з описом void * efct(char *s);

(с) Гроза П.М.

Слайд 45

Приклад

#include
#include
void print(char *s)
{
puts(s);
}
main( )
{

Приклад #include #include void print(char *s) { puts(s); } main( ) {
void (*efct)(char *s);
efct=&print; /* efct=print */
(*efct)("Function Print!"); /* efct("Function Print!"); */
}
Результат
Function Print!

(с) Гроза П.М.

Имя файла: Опис-та-використання-функцій.pptx
Количество просмотров: 102
Количество скачиваний: 0