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

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

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

Всі стандартні засоби зібрані у спеціальні набори — стандартні бібліотеки, які, зазвичай, повинні бути підключені в тексті програми. Наприклад, у програмах на мові Р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“);

}

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

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