69102

Локалізація імен. Різновиди параметрів. Процес виклику підпрограм

Лекция

Информатика, кибернетика и программирование

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

Украинкский

2014-09-30

89.5 KB

0 чел.

Лекція 11. Тема:Локалізація імен.Різновиди параметрів.Процес виклику підпрограм.

                             Програмний стек.Процедурні типи.

План:

1. Підпрограми, їх різновиди та способи використання

2. Функції користувача

3. Стандартні процедури та функції

1. Підпрограми, їх різновиди та способи використання

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

Отже підпрограма — це іменована частина програми, котра описує деякі обчислення і може бути викликана з будь якого місця програми, де синтаксисом мови це не заборонено. Таким чином, для багаторазового виконання деякого програмного коду достатньо записати його один раз у підпрограмі, і надалі, в разі потреби, вказувати лише її ім'я. Концепція програмування, що ґрунтується на використанні підпрограм як стандартних блоків для створення нових програм, отримала назву повторне використання коду. Мови, в яких реалізовано механізми використання підпрограм, називаються процедурно-орієнтованими. Мова Pascal належить до таких мов. Символу. Умовою завершення програми може стати натискання користувачем клавіші Esc, що приведе до присвоєння змінній key символу з кодом 27.

Зауважимо, що в результаті роботи калькулятора вікно програми може заповнитись даними розрахунків і тому варто додати до меню таку дію, як знищення результати попередніх обчислень. Цю дію можна виконати стандартною процедурою сіrscr. Проте саме меню під час очищення вікна програми не повинне зникати, тобто дію процедури сіrscr треба обмежити тією областю вікна, у якій виводитимуться результати розрахунків. Таке обмеження здійснює процедура window. Наведемо код основної програми.

program ex4_l:

uses crt:   {модуль crt иістить процедури сіrscr і window

та функцію readkey}
var key:char; {вибраний пункт пеню}

{ begin

сіrscr;

written (‘1 enter data’):

written ( '2 year  by year sum’)

writeln ('3. final sum'): write ('4. clear calculations writeln (ESC - exit1):

writeln (‘======’)

window(1.4.80.25): {виключення пеню з робочої області вікна програми}

repeat

writeln ('choose conmand (1-4 or ESC):'):

key:=readkey:

case key of

"l':Init; {введення даних}

'2':Solution:    {обчислення щорічних сум на рахунку}

'3':Final; {обчислення кінцевої суми}

'4':clrscr;  {очищення робочої області вікна програми}

end; until key=#27: {#27 - код клавіші Esc}

end.

Під час компіляції програми виникне синтаксична помилка Illegal assignment (Недопустиме присвоєння), яка свідчитиме про те, що програмі невідомі ідентифікатори Init, Solution, Browse, Final. Очевидно, ці імена потрібно оголосити до їх використання. Але на відміну від імен змінних згадані імена є назвами процедур, тобто груп операторів, що виконують певні дії. Тому для їх оголошення використовуються інші синтаксичні конструкції. Оголошення процедури або функції записується в розділі оголошень програми і має таку саму структуру, як і вся програма, за винятком крапки наприкінці, замість якої використовується крапка з комою. Синтаксис оголошення процедури є таким:

procedure <ім'я>(<оголошення параметрів>):

<оголошення імен>

begin

<операторна частина процедури>

end:

Тут procedure, begin, end — зарезервовані слова; <ім’я> — унікальний в межах програми ідентифікатор процедури, за яким вона викликається; <оголошення параметрів> — оголошення змінних, яким надаються значення під час виклику процедури; оголошення імен> - розділ оголошень ідентифікаторів, що будуть використовуватись лише в межах процедури; <операторна частина процедури> — оператори, які виконуються під час виклику процедури, їх називають також тілом процедури.

Рядок програми, що містить ключове слово procedure, ім'я процедури та її параметри, називається заголовком процедури. Процедури можуть не мати параметрів, тоді вони називаються процедурами без параметрів, а синтаксис їх оголошення є таким:

procedure <ім'я>: <оголошення імен> begin

<операторна частина процедури>

end:

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

«ім'я процедури:

Продовжимо низхідне проектування калькулятора нарахувань за депозитними внесками. Для того щоб позбутися синтаксичних помилок, слід ті підпрограми, методи реалізації яких ще не визначені, замінити «заглушками», тобто процедурами, які не виконують жодних дій. Зокрема, програма калькулятора успішно компілюватиметься, якщо перед словом begi n записати такі «заглушки»:

procedure Init:

begin

end:

{===}

procedure Browse;

begin

end:

{====}

procedure Solution:

begin

end:

{===}

procedure Final:

begin

end;

Наступний етап розробки програми полягає у кодуванні дій, які мають виконувати процедури. Для реалізації процедури Init потрібно оголосити змінні, що зберігатимуть значення вхідних даних. Нехай це будуть змінні deposit (початкова сума внеску), period (термін дії рахунку) та rate (відсоткова ставка річного прибутку). Сама будова процедури Init є досить очевидною, тому не потребує коментарів.

У процедурі обчислення щорічних нарахувань Solution міститиметься цикл, у якому period разів застосовуватиметься рекурентна формула sum:-sum*(l+rate). Отже, у змінній sum зберігатиметься поточна сума коштів на депозитному рахунку. Оскільки процедура Solution має виводити суму коштів станом на кінець кожного року, то в тілі згаданого циклу повинна викликатися процедура Browse. Якщо номер поточного року зберігати у змінній year, дія процедури Browse обмежиться виведенням значень змінних year та sum, і її будова також є очевидною.

Нарешті, розглянемо процедуру Final. Основна дія цієї процедури - обчислення кінцевої суми за формулою sum = deposit * (1 + rate)period, що на мові Pascal записується так: sum:=deposit*exp(period*ln(l+rate)) (математичні функції та спосіб обчислення степенів детально розглянуто в розділі 4.1.3). Після обчислення значення змінної sum процедура Final має викликати процедуру Browse. Але, оскільки процедура Browse оперує значенням змінної year, цій змінній у процедурі Final повинно бути присвоєне значення змінної period.

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

program ex4_l; {калькулятор нарахувань за депозитними внесками}

uses crt;

var key:char;

deposit:real; {початковий внесок}

period:integer; {термін дії рахунку}

rate:real: {відсоткова ставка річного прибутку}

sum:real; {сума на депозиті}

year:integer; {поточний рік}

procedure Init:

begin

writeln('enter deposit ');

readln(deposit):

writelnCenter period ');

readln(period):

writeln ('enter rate:5..20 '):

readln(rate):

rate:=rate/100; {перетворення цілочислового відсотка

на коефіцієнт rate}

end:

{=== виведення результатів розрахунків===} procedure Browse;

begin

writeln(sum at the end of '.year.' year is '.sum:6:2);

writeln('press enter to continue');

readln;

end:

procedure Solution;

begin

sum:-deposit: {початкове значення sum}

for year:=l to period do

begin

sum:-sum*(l+rate): {рекурентна формула}

browse:

end:

end:

procedure Final:

begin

year:-period:

{розрахунок sum за формулою складних відсотків}

sum:=deposit*exp(Ln(l+rate)*period);

Browse:

end:

Begin

clrscr:

write(l. enter data       '):

write('2. year by year sum )

writelnC'3. final sum'):

write('4. clear calculations ‘)

writeln('ESC - exit');

writeln('===’)

window(l,4.80.25);

repeat

writelnC'choose command (1-4 or ESC):1):

key:-readkey;

case key of

'l':Init:

'2':Solution;

'3':Final:

'4':clrscr;

end:

until key=#27;

end.!

Процедури * параметрами

У програш ех4_1 відбувався обмін даними між процедурами. Зокрема, процедури Solution та Final «передавали» процедурі Browse значення змінних sum та year. Така передача даних дещо порушувала принципи низхідного проектування, оскільки процедури Solution та Final повинні були «знати» внутрішню структуру процедури Browse. В ідеальній ситуації загальновідомим є лише заголовок підпрограми, а її внутрішня будова залишається прихованою від розробників інших підпрограм, програм або модулів. Як за такої ситуації слід модифікувати значення змінних, що використовуються всередині підпрограм? Для цього застосовуються спеціальні змінні, параметри процедури, що оголошуються в її заголовку. Параметри відіграють роль своєрідного буферу між процедурою та «зовнішнім світом»: бажано, щоб усі значення, які надходять до процедури ззовні, були присвоєні її параметрам.

В оголошенні підпрограми імена параметрів записуються в круглих дужках після її назви. Наприклад, змінна х є параметром підпрограми sin(x), що обчислює синус числа х. Під час виклику підпрограми, що має параметри, поруч із її іменем в круглих дужках записуються певні вирази. Значення цих виразів присвоюватимуться параметрам підпрограми. Наприклад, під час виклику sin(3+2) підпрограми sin(x) змінна х набуде значення 5. Значення параметрів підпрограми, що вказуються під час її виклику, називаються аргументами підпрограми.

Розглянемо приклад, що демонструє використання процедур з параметрами.

Приклад

Знайдемо просте число за його номером у послідовності всіх простих чисел. Першими членами цієї послідовності є числа 1, 2, 3, 5, 7, 11.Тому третім за номером простим числом є 3, а п'ятим — 7 тощо. Наведемо спочатку алгоритм розв'язання задачі, а згодом, скориставшись технологією низхідного проектування,
розробимо програму.

Алгоритм пошуку простого числа за його номером.

1. Увести номер простого числа.

2.Покласти початкове значення лічильника простих чисел рівним одиниці.

3.Перше число, що перевіряється, покласти рівним одиниці.

4.Поки лічильник простих чисел не досягне введеного номера, повторювати дії:

5.Перейти до перевірки наступного числа.

6.Якщо число просте, збільшити лічильник простих чисел.

7..Останнє просте число з тих, що переглядалися на кроці 4, і є шуканим.
Проектування програми почнемо з розробки її основної частини, що реалізує
 визначені алгоритмом дії. В алгоритмі використовуються такі змінні величини: номер простого числа, значення якого обчислює програма (number), лічильник простих чисел (j), число, що перевіряється на простоту (n), та ознака того, що число є простим (flag). Змінні number, j та п є, очевидно, цілочисловими, а змінна flag — булевою. Власне перевірку числа на простоту залишимо процедурі ІsSimple, параметрами якої будуть змінні n та f1ag. При цьому значення змінної flag процедура IsSimple змінюватиме. Отже, тіло основної програми матиме такий вигляд:

Begin

writeln('enter number '):

readln(number);         {увести номер простого числа}
J:=l: {поточний номер простого числа}

n:=1:      {початкове значення шуканого простого числа}

while j<number do begin

n:=n+l;

IsSimple(n.flag):

if flag then

end:

writeln('j='.j,' chislo='.n):

end.

Перш ніж записати оголошення процедури IsSimpl e, наведемо повний синтаксис заголовка процедури з параметрами:

procedure <ім’я>(<ім'я:тип>:... <var Ім'я:тип>:...):

Парою <ім'я:тип> позначається ідентифікатор параметра та ідентифікатор його типу. Зазначимо, що параметри одного типу можна об'єднувати в один список: <ім-я1. ім'я2:тип>. Зарезервоване слово var записується перед іменем параметра процедури в тому разі, якщо процедура повинна модифікувати значення змінних, оголошених поза її межами. Так, процедура IsSimple повинна змінювати значення зовнішньої змінної flag. Ім'я такої змінної під час виклику процедури має відповідати параметру, оголошеному зі специфікатором var. Усі модифікації var-naраметра в тілі процедури відбиватимуться і на змінній, що була вказана у виклику процедури як значення цього параметра. Отже, заголовок процедури IsSimple може бути таким:

procedure IsSimplet(a: integer: var b: boolean):

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

Докладніше параметри підпрограм розглядатимуться у розділі 4.1.4, а зараз наведемо повний код програми обчислення простого числа.

program ex4_2: {пошук простого числа за його номером}

var number. {номер шуканого простого числа}

j. {лічильник простих чисел}

n:integer: {число, що перевіряється на простоту}

flag:boolean: {ознака того, що число є простим}

procedure IsSimple(a:іnteger: var b:boolean):

{a - число, що перевіряється на простоту,
b - ознака того, що число просте}
var  k: einteger: {потенційний дільник}

begin

Іс:=2; {вибрати перший дільник}

b:=true:       {ще неиае підстав вважати а складений} {перебирати потенційні дільники} while (k<=trunc(sqrt(a))) and b do

begin

if n mod k =0 then {якщо k ділить n.}

b:=false: {сигналізуємо про це}

k:=k+l: {наступний потенційний дільник}

end: end:

begin

writeln('enter number '); readln(number):

j:=1;

n:=1;

while j<number do

begin

n:=n+l;

IsSimple(n.flag):

if flag then

j:=j+l: end:

writeln( j='.j,' prime='.n):

end.

2. Функції користувача

Окрім підпрограм-процедур у мові Pascal використовуються підпрограми-функції. В математиці за допомогою функцій задають залежності між змінними-аргументами та змінними-значеннями функції. Щ залежності можна задавати аналітичним, графічним, табличним та іншими способами. В алгоритмічних мовах розглядаються тільки ті функції, для яких можна задати алгоритм обчислення їх значень. Програмний опис певного алгоритму обчислення значень називається функцією. Ім'ям функції, використаним в тексті програми, позначається виклик функції. Як уже зазначалося, функція відрізняється від процедури тим, що повертає деяке значення в точку 5 виклику, тобто під час виклику функції u ім'я може інтерпретуватись як ім'я деякої змінної величини. А отже, функцію, на відміну від процедури, можна викликати у виразах. Наприклад, вираз sin(5)+1 є коректним у тому разі, коли sin(x) — функція, і некоректним, якщо sin(x) — процедура.

Приклад

Обчислимо довжини сторін трикутника, заданого координатами вершин. Зрозуміло, що основною дією в цій задачі є обчислення відстані між двома точками на площині. Відстань d між двома точками з координатами (at; b{), (a2; b2) визначається за формулою d =. Якщо задачу розв'язувати без використання функцій, то цю формулу доведеться запрограмувати тричі. Застосування функції, що обчислює відстань між двома точками, дасть можливість запрограмувати вищезгадану формулу лише один раз, але при цьому тричі здійснюватиметься виклик функції. Другий шлях є ефективнішим, адже запрограмувати виклик функції у загальному випадку значно легше, ніж переписати її операторну частину. Наведемо синтаксис оголошення функції.

function <ім'я>(<оголовення параяетрів>):<ім'я типу>:

<оголошення імен>

begin

<операторна частина функціі> end:

Тут function, begin, end - зарезервовані слова; <ім"я> — ідентифікатор функції, за яким здійснюється її виклик; <оголошення параметрів> — необов'язковий список змінних та їх типів, синтаксис якого збігається із синтаксисом оголошення параметрів процедури; <ім"я  типу> - тип значення, що повертається функцією; <оголошення  імен > — розділ оголошень ідентифікаторів, які використовуватимуться лише в межах функції; <операторна частина функції> - оператори, що реалізують алгоритм обчислення значення функції, їх називають також тілом функції.

Ключове слово function, ім'я функції, оголошення її параметрів і тип значення, що вона його повертає, становлять заголовок функції. Структура тіла функції повторює структуру програми: спочатку в тілі функції записуються оголошення ідентифікаторів, які в ній використовуються, а потім — оператори, що виконуються під час виклику функції.

УВАГА

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

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

program ex4_3: begin

{введення координат вершин трикутника}

{обчислення довжин сторін трикутника}

{виведення результатів}

Init:

Solution:

Browse;

end.

Визначимо змінні, через які відбуватиметься обмін даними між процедурами. Координати вершин зберігатимемо у змінних xl, yl, х2, у2, хЗ, уЗ, а довжини сторін - у змінних dl, d2, d3. Усі ці змінні належатимуть до дійсного типу даних.

Тепер перейдемо до проектування вищезгаданих процедур. Будова процедур Init та Browse є очевидною, а зміст процедури Solution полягає у присвоєнні змінним dl, d2 та d3 значень, що дорівнюють відстаням між парами вершин. Ці відстані обчислюватимуться функцією Distance. Процедура Solution матиме такий вигляд:

procedure Solution;

begin

{відстані}

{від (xl.yl) до (х2.у2)}

{від (х2.у2) до (хЗ.уЗ)}

{від (xl.yl) до (хЗ.уЗ)}

dl:=Distance(xl.yl.x2.y2

d2:=Distance(x2.y2.x3.y3):

d3:=Distance(xl.yl.x3.y3):

end;

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

function Distancet(al.bl.а2.b2:real):real;

begin

Distance:=sqrt(sqr(al-a2)+sqr(bl-b2)): end;

Наведемо повний код програми ех4_3 разом з оголошеннями процедур і функції

program ex4_3:      {обчислення довжин сторін трикутника}
var Xl.yl.x2.y2.x3.y3:real;   {координати вершин трикутника}
dl.d2.d3:real: {довжини сторін трикутника}

function Distance(al.bl.a2.b2:real):real:

begin

Distance:-sqrt(sqr(al-a2)+sqr(bl-b2)):

end:

procedure Init:

begin

writeln('enter triangle apexes coordinates'):

writet('coordinates xl.yl '); readln (xl.yl):

writet('coordinates x2.y2 '); readln (x2.y2);

writet('coordinates хЗ.уЗ '): readln (хЗ.уЗ):

end:

procedure Solution:

begin

dl:-Distance(xl.yl.x2.y2):

d2:-Distance(x2.y2.x3.y3):

d3:-Distance(xl.yl.x3.y3): end;

procedure Browse:

begin

writeln(‘lengthl='. dl:6:2):

writeln('length2='. d2:6:2);

writeln('length3='. d3:6:2):

end:

 основна програна

begin

Init:

Solution:

Browse:

end.

3. Стандартні процедури та функції

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

Математичні процедури та функції реалізують найбільш поширені математичні операції. Тип аргументу функції може бути як цілим, так і дійсним. Більшість функцій повертає значення типу real, а в режимі компіляції з використанням сопроцесора або з його емуляцією - значення типу extended. Деякі функції повертають значення, тип якого залежить від типу аргументу.

Контрольні питання

1. Підпрограми, їх різновиди та способи використання

2. Функції користувача

3. Стандартні процедури та функції


 

А также другие работы, которые могут Вас заинтересовать

34658. Основы визуального программирования. Пустая форма и ее модификация. Компоненты страницы Standart 5.01 MB
  Если это свойство равно true то окно будет прозрачным. Степень прозрачности задаётся через свойство lphBlendVlue. nchors Это свойство есть и у формы и у компонентов. Это свойство раскрывающееся.
34659. Графические возможности Delphi, система координат 407.3 KB
  Методы вывода графических примитивов рассматривают свойство Cnvs как некоторую поверхность на которой можно рисовать. Координаты области вывода Метод построения графического примитива в общем случае имеет следующий синтаксис...
34660. Динамические структуры данных. Стеки, очереди. Списки. Бинарные деревья 178.5 KB
  При создании дерева вызывается рекурсивная процедура следующего вида: procedure Insertvr Root: TTree; X: T; { Дополнительная процедура создающая и инициализирующая новый узел } procedure CreteNodevr p: TTree; n: T; begin Newp; p^.Right := nil end; begin if Root = nil Then CreteNodeRoot X { создаем новый узел дерева } else with Root^ do begin if vlue X then InsertRight X else if vlue X Then InsertLeft X else { Действия производимые в случае повторного...
34661. Доступ к системным ресурсам. Определение переменной как Absolute. Предопределенные массивы MEM. Прерывания. Обработка прерываний 66 KB
  Прерывания. Прерывания Прерывание это особое состояние вычислительного процесса. В момент прерывания нарушается нормальный порядок выполнения команд программы и управление передается специальной процедуре которая входит в состав ДОС и называется процедурой обработки прерывания. В архитектуре центрального процессора ПК предусмотрены прерывания двух типов аппаратные и программные.
34662. Введение. История развития языков программирования 38.76 KB
  На занятиях по дисциплине АО мы будем изучать язык Паскаль. Паскаль язык программирования который относительно прост в изучении довольно ясен и логичен и будучи первым изучаемым языком программирования приучает к хорошему стилю. Паскаль стал наследником Алгола. Время рождения языка Паскаль начало 70х годов.
34663. Итерационные алгоритмы 41 KB
  Особенностью итерационного цикла является то что число повторений операторов тела цикла заранее неизвестно. Выход из итерационного цикла осуществляется в случае выполнения заданного условия. Особенностью же нашей конкретной задачи является то что число слагаемых а следовательно и число повторений тела цикла заранее неизвестно. Поэтому выполнение цикла должно завершиться в момент достижения требуемой точности.
34664. Основы комбинаторики 56 KB
  При выборе m элементов из n различных элементов принято говорить что они образуют соединение из n элементов по m. Перестановка Соединение каждое из которых содержит n различных элементов взятых в определенном порядке называются перестановками из n элементов n=m. Сочетание Соединения отличающиеся друг от друга каждое из которых содержит m элементов взятых из n элементов называется сочетанием из n элементов по m n m. Размещение с повторением Размещение из n элементов в каждое из которых входит m элементов причем один и тот же...
34665. Компоненты страницы Win32, их назначение, свойства, примеры применения 1.34 MB
  Свойства компонента: property DisplyRect: TRect; Определяет рабочую зону компонента предназначенную для размещения других компонентов. Клиентская часть компонента содержит зону закладок и рабочую зону property HotTrck: Boolen; Если содержит True название закладки автоматически выделяется цветом при перемещении над ней указателя мыши property Imges: TCustomImgeList; Определяет объект хранилище изображений которые будут прорисовываться слева от текста property MultiLine: Boolen; Разрешает расположение закладок в несколько рядов. Если...
34666. Массивы: определение, описание, размещение в памяти, использование 55 KB
  Структурная схема массива. Type имя типа = RRY [ тип индекса ] OF тип элементов VR имя переменной : имя типа ; При таком способе описания в разделе Type описывается тип массива который будет использоваться в программе то есть его размер и тип элементов. С отдельным элементом массива можно делать все что с любой переменной. Обращаться к элементу массива надо указывая имя переменной с номером элемента в квадратных скобках.