Функції в сі

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

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

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

Ми вже знайомі з багатьма функціями і знаємо, як їх викликати - це функції бібліотек stdio, stdlib, string, conio тощо. Більш того, main - це теж функція. Вона відрізняється від інших тільки тим, що є точкою входу під час запуску програми.
Функція в сі визначається в глобальному контексті. Синтаксис функції:

Найпростіший приклад - функція, яка приймає число типу float і повертає квадрат цього числа

Усередині функції sqr ми створили локальну змінну, якій присвоїли значення аргументу. Як аргумент функції передали число 9,3. Службове слово return повертає значення змінної tmp. Можна переписати функцію наступним чином:

В даному випадку спочатку буде виконано множення, а після цього повернення значення. У тому випадку, якщо функція нічого не повертає, типом значення, що повертається буде void. Наприклад, функція, яка друкує квадрат числа:

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

Якщо функція не приймає аргументів, то дужки залишають порожніми. Можна також написати слово void:

Формальні і фактичні параметри

Наприклад, нехай є функція, яка повертає квадрат числа і функція, яка підсумовує два числа.

Звертаю увагу, що приведення типів просіходіт неявно і тільки тоді, коли це можливо. Якщо функція отримує число як аргумент, то не можна їй передати змінну рядок, наприклад "20" і т.д. Взагалі, краще завжди використовувати вірний тип або явно приводити тип до потрібного.
Якщо функція повертає значення, то воно не обов'язково має бути збережено. Наприклад, ми користуємося функцією getch, яка зчитує символ і повертає його.

передача аргументів

У програмуванні перший спосіб передачі параметрів називають передачею за значенням, другий - передачею за вказівником. Запам'ятайте просте правило: якщо ви хочете змінити змінну, необхідно передавати функції покажчик на цю змінну. Отже, щоб змінити покажчик, необхідно передавати покажчик на покажчик і т.д. Наприклад, напишемо функцію, яка буде приймати розмір масиву типу int і створювати його. З першого погляду, функція повинна виглядати якось так:

Для зміни об'єкта необхідно передавати покажчик на нього, в даному випадку - покажчик на покажчик.

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

Це змішана рекурсія - функція odd повертає 1, якщо число непарне і 0, якщо парне.

Давайте створимо просту бібліотеку. Для цього потрібно буде створити два файли - один з розширенням .h і помістити туди прототипи функцій, а інший з розширенням .c і помістити туди визначення цих функцій. Якщо ви працюєте з IDE, то .h файл необхідно створювати в папці Заголовки, а файли коду в папці Файли вихідного коду. Нехай файли називаються File1.h і File1.c
Перепишемо попередній код. Ось так буде виглядати заголовки File1.h

Вміст файлу вихідного коду File1.c

Наша функція main

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

Заголовки, як і обмовлялося раніше, містить прототип функцій. Також тут можуть бути підключені використовувані бібліотеки. Макрозащіта #define _FILE1_H_ і т.д. використовується для запобігання повторного копіювання коду бібліотеки при компіляції. Ці рядки можна замінити однією

Передача масиву як аргумент

До ак вже говорилося раніше, ім'я масиву підміняється на покажчик, тому передача одновимірного масиву еквівалентна передачі покажчика. Приклад: функція отримує масив і його розмір і виводить на друк:

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

Також нагадаю, що правило підміни масиву на курсор не рекурсивне. Це означає, що необхідно вказувати розмірність двовимірного масиву при передачі

Або, можна писати

Якщо двовимірний масив створений динамічно, то можна передавати покажчик на покажчик. Наприклад функція, яка отримує масив слів і повертає масив цілих, рівних довжині кожного слова:

Можна замість того, щоб повертати покажчик на масив, передавати масив, який необхідно заповнити

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

ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 [email protected] Stepan Sypachev students