Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1 (6).doc
Скачиваний:
45
Добавлен:
12.05.2015
Размер:
1.67 Mб
Скачать

ПЛАН

ПРОЦЕДУРНО-ОРІЄНТОВАНЕ ПРОГРАМУВАННЯ 1

Організація підпрограм 1

Поняття підпрограми 1

Організація підпрограм 2

Механізм передачі параметрів 6

Принцип локалізації 9

Концепція розподілу пам’яті 10

11

Способи передачі параметрів 11

Вказівники на функції 17

Розширені можливості використання підпрограм 19

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

Перевантаження функцій 21

Шаблони функцій 22

Вбудовані функції 24

Рекурсія 24

Процедурно-орієнтоване програмування Організація підпрограм Поняття підпрограми

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

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

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

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

Підпрограми, які використовуватимуться в програмі, повинні бути попередньо визначені(описані). При цьому кожній підпрограмі дається своє ім'я, а також описуються дії,які вона буде виконувати. РБНФ визначення підпрограми має вид:

опис_підпрограми = заголовок блок.

Як видно, структурна організація підпрограм передбачає, що будь-яка підпрограма складається із заголовка і блока (тіла підпрограми). Заголовок підпрограми містить її ім'я і деяку додаткову інформацію, що уточнює використання цієї підпрограми. Тіло підпрограми є тим програмним фрагментом, який описує виконувані підпрограмою дії.

Виклик підпрограми здійснюється за її іменем спеціальною конструкцією виклику. При активізації підпрограми запам'ятовуєтьсятак звана точка поверненняв основну програму і керування передається підпрограмі (її першому оператору). Точка повернення – це місце в програмі, що описує дію, якоюпрограмапродовжується післязавершення виконанняпідпрограми.Це може бути наступний за викликомпідпрограми оператор, умова завершення чи продовження циклу, якщо виклик записаний останнім у тілі циклу, тощо. Після завершення виконання підпрограми відбувається автоматичне повернення в основну програму, яка продовжує своє виконання з дії, що була позначена як точка повернення. Схема взаємодії програми і підпрограми наведена на рис.1.

Рис. 1. Схема взаємодії програми і підпрограми

Використання підпрограм втілює загальний принцип «розділяй і пануй», дозволяє створювати добре структуровані й зрозумілі програми, суттєво полегшує їх проектування та розробку.

Організація підпрограм

Підпрограмиподіляються на стандартні і визначені користувачем. Перші входять до складу мови програмування і викликаються для виконання за строго фіксованими іменами. Другі розробляються самим користувачем.

Всі стандартні засоби зібрані у спеціальні набори — стандартні бібліотеки, які, зазвичай, повинні бути підключені в тексті програми. Наприклад, у програмах на мові Рascal відповідні бібліотеки слід підключити у розділі uses; у мовах С/С++ для цього служить директива препроцесора include.

Зпрактичної точки зорузнаннястандартнихпідпрограмє кориснимі необхідним, адже застосовувати готові деталі набагато легше, ніж створювати їх самому. Проте запрограмувати розв’язання «всіх можливих підзадач» — утопія, тому програмістам доводиться постійно створювати власні підпрограми.

Реалізація підпрограм може різнитися в залежності від мови програмування і залежить, в основному, від можливостей повернення ними значень. Синтаксис же деяких мов програмування не залежить від того, повертаються значення підпрограмами чи не повертаються. Наприклад, Maple не звертає на це увагу; у мовах С/C++ вважається, що значення повертається підпрограмою зав­жди, тільки інколи воно може мати так званий пустий тип (void); в Pascal розрізняють підпрограми-функції, щозавжди по­вертають значення і завжди тільки одне, та підпрограми-процедури, що можуть не повертати значень.

Досить часто результатом роботи під­програми має бути не одне, а декілька різних значень. В такому випадку ви­користовуються різноманітні спеціалізовані методи повернення комплексу значень. Найпростіший із них - використання параметрів-змінних, найефе­ктивніший - утворення блоку результатів і повернення адреси цього блоку, як результату роботи програми. В Maple використовується саме останній метод, тоді як Pascal і C/C++ — використовують і перший, і другий методи.

Розглянемо більш детально реалізацію підпрограм у мовах С/С++. У цих мовах підпрограми існують лише у вигляді функцій. Функції забезпечують зручний спосіб окремого оформлення деяких обчислень з можливістю їх подальшого використання по імені (без турботи про те, як виконана реалізація). РБНФ визначення функції у С/С++:

опис_функції = заголовок тіло_функції;

заголовок = тип_результату ім'я_функції ( [список_параметрів]);

тіло_функції = { {оголошення_змінної |визначення_змінної |оператор} }“.

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

Формат визначення функції представляється наступним чином:

тип_результату ім'я_функції ( [список_параметрів])

{ тіло_функції

}

Повернення значення із функції виконується оператором return наступного формату:

return [вираз].

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

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

int MAX (int a, int b) //обчислення більшого із двох чисел

{ if (a>b) return a;

else return b;

}

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

void PRINT( )

{ cout<<“Нellow!”<< endl;

}

У цьому випадку керування із функції повертається:

  1. по досягненні кінця тіла функції (символа «}»);

  2. при виконанні пустого оператора return.

Активізація функції здійснюється оператором виклику. Його РБНФ:

оператор_виклику_функції = ім'я_ функції “(“ [список_аргументів] “)“.

Оператор виклику може бути як окремим оператором програми, так і операндом виразу. Це залежить від того, чи повертає функція значення у точку виклику: якщо функція не повертає значення у точку виклику, то вона викликається окремим оператором програми, інакше – як операнд виразу.

Розглянемо наступну задачу: для заданих дійсних значень х і у обчислити v = mах(9.5, u), де u = mах(х+у, х*у).

Фрагмент програми розв’язання цієї задачі без використання підпрограм можна представити наступним чином:

// variant 1

int main()

{ float x, y, // вхідні дані

u, v; // результати обчислень

cout <<“Input x, y:”;

cin >> x >> y;

if (x+y > x*y) u=x+y; else u=x*y;

if (9.5>u) v=9.5; else v=u;

cout<<“u=“<<u<<“ v=“<<v<<endl;

system(“pause“);

}

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

Щоб підкреслити схожість двох згаданих вище умовних операторів, запишемо програму трохи інакше:

// variant 2

int main()

{ float x, y, // вхідні дані

n1, n2, m; // допоміжні дані

u, v; // результати обчислень

cout <<“Input x, y:”;

cin >> x >> y;

n1=x+y; n2=x*y;

if (n1>n2) m=n1; else m=n2;

u=m;

n1=9.5; n2=u;

if (n1>n2) m=n1; else m=n2;

v=m;

cout<<“u=“<<u<<“ v=“<<v<<endl;

system(“pause“);

}

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

void F_MAX();

{ if (n1>n2) m=n1;

else m=n2;

}

Для активації цієї функції в потрібному місці програми достатньо записати там оператор виклику даної функції, що складається лише з її імені, - F_MAX. З використанням такої функції вихідна програма прийме вигляд:

// variant 3

// ======== визначення максимального значення ========

void F_MAX()

{ if (n1>n2) m=n1;

else m=n2;

}

//========== головна функція =============================

int main()

{ float x, y, // вхідні дані

n1, n2, m; // допоміжні дані

u, v; // результати обчислень

cout <<“Input x, y:”;

cin >> x >> y;

n1=x+y; n2=x*y;

F_MAX();

u=m;

n1=9.5; n2=u;

F_MAX();

v=m;

cout<<“u=“<<u<<“ v=“<<v<<endl;

system(“pause“);

}

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

float F_MAX();

{ if (n1>n2) return n1;

else return n2;

}

Тоді вихідна програма прийме наступний вигляд:

// variant 4

// ======== визначення максимального значення ========

float F_MAX ()

{ if (n1>n2) return n1;

else return n2;

}

//========== головна функція =============================

int main()

{ float x, y, // вхідні дані

n1, n2; // допоміжні дані

u, v; // результати обчислень

cout <<“Input x, y:”;

cin >> x >> y;

n1=x+y; n2=x*y;

u = F_MAX ();

n1= 9.5; n2=u;

v = F_MAX ();

cout<<“u=“<<u<<“ v=“<<v<<endl;

system(“pause“);

}

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]