ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 10.08.2024
Просмотров: 5
Скачиваний: 0
Технологія створення програм
Лабораторна робота №3_2
Дана лабораторна робота має бути виконана групою студентів. Група студентів отримує загальне завдання, яке є сукупністю підзадач-модулів. Кожен студент є членом команди і виконуює одне із завдань. Один з членів групи, будучи керівником проекту, здійснює керівництво проекту (визначає складність завдань, розподіляє роботу і конролирует процес її виконання).
Результатом роботи групи є програма, що складається з окремих модулів, що мають загальний інтерфейс.
Керівник проекту контролює процес виконання роботи, написання звіту і представляє роботу викладачеві, дає оцінку роботи кожного члена команди.
Лабораторна робота розрахована на 6 годин виконання:
1 Заняття (2 години):
-
видача індивідуальних завдань;
-
розробка плану виконання робіт групою (розподіл ролей в команді, розподіл завдань, розробка єдиного інтерфейсу);
-
розробка алгоритмів, написання код кожним членом команди.
2 Заняття (2 години):
-
тестування код;
-
написання звітів-інструкцій;
-
вироблення одного загального звіту.
3 Заняття (2 години):
-
захист лабораторної роботи (виконується керівником групи);
-
оцінка вкладу кожного члена команди.
Звіт повинен містити:
-
Тему і мету лабораторної роботи;
-
Блок-схему алгоритму;
-
Коди кожного завдання;
-
Інструкцію по роботі.
Тема: Визначення функції. Звернення до функції.
У Сі використовується лише один тип підпрограм — функція. Тут взагалі не прийнято використовувати термін «підпрограма», тому що функція є основною програмною одиницею в Сі, мінімальним виконуваним програмним модулем. Всяка програма обов'язково включає основну функцію з ім'ям main. Якщо в програмі використовуються і інші функції, то вони виконують роль підпрограм.
Розглянемо приклад. Потрібно скласти програму знаходження найбільшого значення з трьох величин — max (а, b, c). Для її вирішення можна використовувати допоміжний алгоритм знаходження максимального значення з двох, оскільки справедлива рівність: max (а, b, c) = max (max (а, b, c).
Ось програма рішення цієї задачі з використанням допоміжної функції.
Приклад 1.
Формат визначення функції наступний:
тип ім'я_функції (специфікація_параметрів)
{тіло_ функції}
Тип функції — це тип повертаного функцією результату. Якщо функція не повертає жодного результату, то для неї вказується тип void.
Ім'я функції — ідентифікатор, що задається програмістом або main для основної функції.
Специфікації параметрів — це або «порожньо», або список імен формальних параметрів функції з вказівкою типа для кожного з них.
Тіло функції — це або складений оператор, або блок.
Ознакою блоку є наявність описів програмних об'єктів (змінних, масивів і так далі), які діють в межах цього блоку. Блок, як і складений оператор, обмежується фігурними дужками.
У Сі діє правило: тіло функції не може містити в собі визначення інших функцій.
Оператором повернення з функції в точку її виклику є оператор return. Він може використовуватися у функціях в двох формах:
return; або return вираження;
У першому випадку функція не повертає жодного значення як свого результату. У другому випадку результатом функції є значення вказаного вираження. Тип цього виразу повинен або збігатися з типом функції, або належати до типів, що допускають автоматичне перетворення до типа функції.
Оператор return може в явному вигляді бути відсутнім в телі функції. В такому разі його присутність мається на увазі перед функції, що закриває тіло, фігурною дужкою. Така підстановка проводиться компілятором.
Формат звернення до функції (виклику функції) традиційний:
ім'я_функції(список_фактичних_параметрів)
Між формальними і фактичними параметрами при виклику функції повинні дотримуватися правила відповідності по послідовності і по типах. Фактичний параметр — це вираження того ж типа, що і у відповідного йому формального параметра. Стандарт мови Сі допускає автоматичне перетворення значень фактичних параметрів до типа формальних параметрів. У Си++ таке перетворення не передбачене.
Передача параметрів при виклику функції відбувається лише за значенням.
Прототип функції. Виявляється, зовсім не обов'язково було в попередньому прикладі поміщати повне визначення функції МАХ() перед основною частиною програми. Ось інший варіант програми, вирішальної те ж саме завдання.
Приклад 2.
Тут використаний прототип функції. Прототипом називається попередній опис функції, в якому містяться всі необхідні відомості для правильного звернення до неї: ім'я і тип функції, типи формальних параметрів. У прототипі імена формальних параметрів вказувати необов'язково (як це зроблено в прикладі 2), хоча їх вказівка не є помилковою. Можна було написати і так, як в заголовку визначення функції:
int MAX(int x, int у);
Крапка з комою в кінці прототипу ставиться обов'язково! Можна було б записати прототип і в телі основної функції разом з описами інших програмних об'єктів в ній. Питання про розміщення описів пов'язане з поняттям зони видимості, який буде обговорений трохи пізнішим.
У наступній програмі наводиться приклад використання функції, яка не має параметрів і не повертає жодних значень в точку виклику. Ця функція малює на екрані рядок, що складається з 80 зірочок.
Приклад 3.
якщо основна частина програми є функцією, то хто (або що) її викликає? Відповідь полягає в наступній: програму викликає операційна система при запуску програми на виконання. І в принципі main-функция зовсім не обов'язково повинна мати типа void. Наприклад, вона може повертати операційній системі ціле значення 1 як ознака благополучного завершення програми і 0 — в «аварійному» випадку. Обробка цих повідомлень здійснюватиметься системними засобами.
Використання бібліотечних функцій. Бібліотечними називаються допоміжні функції, що зберігаються в окремих файлах. Стандартні бібліотеки входять в стандартний комплект системи програмування на Си/Си++. Крім того, програміст може створювати власні бібліотеки функцій. Раніше вже говорилося про те, що для використання стандартних функцій необхідно підключати до програми заголовні файли відповідних бібліотек. Робиться це за допомогою директиви претранслятора #include з вказівкою імені заголовного файлу. Наприклад, #include <stdio.h>. Всі заголовочні файли мають розширення h (від англійського header). Тепер повинно бути зрозуміло, що ці файли містять прототипи функцій бібліотеки. На стадії претрансляции відбувається підстановка прототипів перед основною функцією, після чого компілятор в змозі контролювати правильність звернення до функцій. Самі програми, що реалізовують функції, зберігаються у формі об'єктної коди і підключаються до основної програми на стадії редагування зв'язків (при роботі компонувальника).
Розглянемо програму рішення наступної задачі: знаючи декартові координати вершин опуклого чотирикутника, обчислити його площу.
Математичне рішення цієї задачі наступне. Позначимо координати вершин чотирикутника так: (х1,у1), (х2,у2), (х3, у3), (х4, у4). Площу чотирикутника можна обчислити як суму площ двох трикутників. У свою чергу, площа кожного трикутника обчислюється за формулою Герона. Для вживання формули Герона потрібно знайти довжини сторін. Довжина сторони між першою і другою вершинами обчислюється за формулою:
Аналогічно обчислюються довжини інших відрізань.
Таким чином, для вирішення основного завдання — обчислення площі чотирикутника — потрібний допоміжний алгоритм обчислення площі трикутника, для якого, у свою чергу, необхідний допоміжний алгоритм обчислення довжини відрізання по координатах кінців.
Нижче приведена програма рішення поставленої задачі.
Приклад 5.
У цій програмі використовуються функції з трьох стандартних бібліотек із заголовними файлами iostream.h, math.h і conio.h. З першими двома ми вже зустрічалися раніше. Третя бібліотека (файл conio.h) містить функції, призначені для управління виводом на екран в символьному режимі. Вона є аналогом модуля CRT в Турбо Паськале. У програмі з цієї бібліотеки використовується функція clrscr () — очищення екрану.
Ще одним новим елементом в приведеній програмі є рядок
typedef double D;
Службове слово typedef є специфікатором типа, що дозволяє визначати синоніми для позначення типів. В результаті в даній програмі замість довгого слова double для позначення того ж самого типа можна вживати одну букву D. Даний опис діє глобально і поширюється як на основну, так і на допоміжні функції.
У функції Geron є звернення до функції Line, а в основній функції — звернення лише до функції Geron. Для компілятора важливо, аби перед функцією був присутній або прототип, або визначення функції, що викликається. Тому якщо з даної програми прибрати прототип функції Line, то помилки не буде. Але якщо одночасно з цим поміняти місцями визначення функцій Line і Geron, то компілятор видасть повідомлення про помилку.
Рекурсивні визначення функцій. Допускається рекурсивне визначення функцій. Проілюструємо визначення рекурсивної функції на класичному прикладі обчислення факторіалу цілого позитивного числа.
У випадку якщо при виклику функції буде заданий негативний аргумент, вона поверне нульове значення — ознаку невірного звернення.
Передача значень через глобальні змінні. Зоною дії опису програмного об'єкту називається частина програми, в межах якої діє (враховується) цей опис. Якщо змінна описана усередині деякого блоку, то вона локалізована в цьому блоці і з інших блоків, зовнішніх по відношенню до даного, «не видна». Якщо опис змінною знаходиться поза блоком і передує йому в тексті програми, то цей опис діє усередині блоку і називається глобальним. Глобальна змінна «видно» з блоку. Наприклад:
double x ;
int funcl()
(int у;... }
void main()
{float в;...}
Змінна x є глобальною по відношенню до функцій funcl, main і, отже, може в них використовуватися. У функціях funcl і main є локальні змінні з однаковим ім'ям в. Проте це різні величини, ніяк не зв'язані один з одним. Оскільки змінна х є загальною для обох функцій, то вони можуть взаємодіяти через х один з одним.
При зверненні до функції передача значень можлива як через параметри, так і через глобальні змінні. У наступній програмі вирішується завдання здобуття найбільшого з трьох значень.
Приклад 6.
Результат виконання функції MAX заноситься в глобальну змінну z, яка «видно» також і з основної функції
Тому при другому зверненні ця змінна грає одночасно роль аргументу і результату. Тут оператор звернення до функції виглядає подібно до звернення до процедури в Паськале, а глобальна змінна z грає роль var-параметра.
Класи пам'яті. Під всяку змінну, використовувану в програмі, має бути виділене місце в пам'яті ЕОМ. Виділення пам'яті може відбуватися або на стадії компіляції (компоновки) програми, або під час її виконання. Існують 4 класи пам'яті, що виділяється під змінні:
• автоматична (ключове слово auto);
• зовнішня (extern);
• статична (static);
• регістрова (register).
Під глобальні змінні виділяється місце в зовнішній пам'яті (не потрібно думати, що йдеться про магнітній пам'яті; це оперативна пам'ять класу extern). Глобальну змінну можна оголосити або поза програмними блоками, або усередині блоку з ключовим словом extern. Зазвичай це робиться в тих випадках, коли програмний модуль зберігається в окремому файлі і, отже, окремо компілюється.