Синтаксис опису і виклику процедури h2>
Курсова робота p>
Виконав Дзотцоев Лев Казгеріевіч p>
Північно-Кавказький гірничо-металургійний інститут
(СКГТУ) p>
Кафедра промислової електроніки p>
Факультет електронної техніки, ПЕ-04-1 p>
Владикавказ 2004 рік p>
Завдання h2>
Наведіть
синтаксис опису і виклику процедури. Опишіть види, призначення формальних і
фактичних параметрів. Наведіть приклад опису процедури, її виклику і
поясніть його. p>
Дани
цілі m та n. Скласти програму
обчислення p>
x = (m! + n!)/(m + n)!, де k = 1x2x3x4x .. xK p>
В
програмі передбачити: p>
Введення
m і n p>
Опис
процедури-функції для обчислення значення факторіалу: f (k) = k! =
1x2x3x .. xK p>
Відображення
на екрані дисплея значення Х p>
Коментарі
в основних місцях програми p>
2.1
Налагодити і провести рахунок за програмою. P>
2.2
Привести в пояснювальній записці: p>
Текст
програми з поясненнями p>
Вихідні
дані та результати рахунки p>
Синтаксис опису і виклику процедури. h2>
Програма
об'ємом до 10000 операторів вважається малою, до 100000 операторів - середнього.
Зрозуміло, що будувати такі програми безпосередньо з елементарних операції
практично неможливо. Для спрощення розробки програм в Pascal-е можна використовувати підпрограми
- Процедури та функції. Вони являють собою інструмент, за допомогою якого
будь-яка програма може бути розбита на ряд певною мірою незалежних один
від одного частин. Таке розбиття необхідно з двох причин. p>
По-перше,
це засіб економії пам'яті: кожна підпрограма існує в програмі в
одному примірнику, в той час як звертатися до неї можна багато разів з
різних точок програми. При виклику підпрограми активізується
послідовність утворюючих її операторів, а за допомогою переданих
підпрограмі параметрів потрібним чином модифікується реалізований в ній
алгоритм. p>
Друга
причина полягає в застосуванні сучасних методів спадного проектування
програм. В результаті застосування цих методів алгоритм представляється у вигляді
послідовності щодо великих підпрограм, що реалізовують більш -
менш самостійні смислові частини алгоритму. Підпрограми у свою чергу
можуть розбиватися на менш великі підпрограми, ті - на підпрограми нижнього
рівня і т.д. Послідовне структурування програми продовжується до тих
пір, поки що реалізуються підпрограмами алгоритми не стануть настільки простими,
щоб їх можна було легко запрограмувати. p>
Pascal навіть у порівнянні з
промисловими системами програмування має дуже потужними засобами
роботи з підпрограмами. p>
Процедури
і функції, як вже зазначалося, являють собою відносно самостійні
фрагменти програми, оформлені особливим чином та обладнаний ім'ям. Згадування
цього імені в тексті програми називається викликом процедури (функції). Відмінність
функції від процедури полягає в тому, що результатом виконання операторів,
що утворюють тіло функції, завжди є деяке єдине значення
простого, строкового типу або покажчика, тому звернення до функції можна
використовувати у відповідних виразах поряд зі змінними і константами. p>
В
структурі Pascal
програм існує спеціальний розділ для опису процедур і функцій. Як
відомо, будь-яке ім'я в програмі має бути обов'язково описано перед тим, як
воно з'явиться серед виконуваних операторів. Чи не робиться винятку і відносно
процедур: кожну необхідно описати в розділі описів. p>
Описати
підпрограму - це означає вказати її заголовок і тіло. У заголовку оголошуються
ім'я процедури і формальні параметри, якщо вони є. За заголовком слід тіло
підпрограми, що складається із розділу описів і розділу виконуваних
операторів. У розділі описів процедур можуть зустрітися опису процедур
нижчого рівня, у тих - опису інших підпрограм і т.д. p>
Синтаксис
і виклик (в загальному) процедур: p>
Procedure p>
Uses p>
Label p>
Const p>
Type p>
Var p>
p>
Begin p>
p>
End; p>
Для
виконання процедури необхідний її виклик. Виклик здійснюється по імені даної
процедури в тілі програми. Назва процедури сприймається як оператор. При його
виконання виконується вся підпрограма. p>
Опис
підпрограми складається із заголовка і тіла підпрограми. p>
Заголовок p>
Заголовок
процедури має вигляд: p>
PROCEDURE (); p>
Тут
- Ім'я підпрограми - список формальних параметрів; p>
(Відразу
за заголовком підпрограми може слідувати один зі стандартних директив
ASSEMBLER, EXTERNAL, FAR, FORWARD, INLINE, INTERRUPT, NEAR) p>
Параметри p>
Параметри
бувають формальні і фактичні. Параметри, що записуються в дужках
після імені процедури, називаються формальними параметрами. Вони вказують на те,
що для виконання цієї процедури необхідні додаткові дані --
фактичні параметри. p>
Список
формальних параметрів необов'язковий, і може бути відсутнім. (Використання
процедур без параметрів виправдано тільки в тому випадку, якщо в них не
використовується звернення до глобальних змінних. Використання таких процедур
обмежено тією програмою, для якої вони написані і утруднене для інших
програм). p>
Якщо
ж він є, то в ньому повинні бути перераховані імена формальних параметрів і їх
тип, наприклад: p>
Procedure YZ (a: real; b: integer:
з: char) p>
Як
видно з прикладу, параметри у списку відокремлюються один від одного крапкою з
комою. Кілька наступних підряд однотипних параметрів можна об'єднувати в
підсписки, наприклад, замість p>
Procedure Z (а: integer; b: integer) p>
можна
написати простіше: p>
Procedure Z (a, b: integer) p>
Оператори
тіла підпрограми розглядають список формальних параметрів як своєрідне
розширення розділу описів: всі змінні з цього списку можуть
використовуватися в будь-яких виразах всередині підпрограми. Таким способом
здійснюється настройка алгоритму підпрограми на конкретне завдання. p>
Перший
формальний параметр замінюється першим фактичним, другу-друга і т. д. p>
Механізм
заміни формальних параметрів на фактичні дозволяє належним чином налаштувати
алгоритм, реалізований у підпрограмі. Турбо Паскаль стежить за тим, щоб
кількість і тип формальні параметрів строго відповідали кількості і типах
фактичних параметрів у момент звернення до підпрограмі. Нагадаємо: сенс
використовуваних фактичних параметрів залежить від того, в якому порядку вони
перераховані при виклику підпрограми. Користувач повинен сам стежити за
правильним порядком перерахування фактичних параметрів при зверненні до
підпрограмі. Наведемо приклад. розглянемо, що цікавить нас частина програми (не
найбільш вдалою, але це поки не важливо) для обчислення x = (5! + 2!)/(5 +2)! p>
Program factorial (input, output); p>
... ... p>
(далі
нас цікавить опис процедури:) p>
Procedure FL (L: integer, var z: integer); (оголошення
процедури, її ім'я, список формальних параметрів) p>
Begin p>
Z: = 1; p>
While L> 1 do p>
Begin p>
Z: = ZxL; (тіло процедури, яка також
передбачає, що 0! і 1! = 1) p>
L: = l-1; p>
end; p>
end; p>
... ... .. p>
begin p>
... ... .. p>
(тепер
розглянемо виклик процедури) p>
FL (5, a); p>
FL (2, b); p>
FL (2 +5, c); p>
.......... p>
end. p>
В
даному випадку l, z формальні
параметри. До речі, їх не треба описувати в розділі глобальних змінних. P>
Фактичні
параметри: 5, а, 2, b,
2 5, c. В "основному"
розділі VAR повинні бути описані а, b, c p>
При
перший виклик процедури фактичний параметр 5 замінить формальний L, фактичний a замінить формальний z, у другому 2 замінить L, b замінить z. p>
В
третьому відповідно 2 5 замінить L, c замінить z.
Для того, щоб остаточно розібратися в програмі, необхідно пояснити,
якими бувають види формальних і фактичних параметрів, їх призначення. p>
Види
параметрів. p>
За
способу передачі даних параметри можна розділити на кілька категорій. p>
Будь-який
з формальних параметрів підпрограми може бути або параметром-значенням,
або параметром-змінною, або параметром-константою. Якщо параметри
визначаються як параметри-змінні, перед ними необхідно ставити
зарезервоване слово VAR, наприклад: p>
Procedure tide (var a: real) Тут параметр А --
параметр-змінна. Заголовок процедури може бути влаштована так, що деякі
групи формальних параметрів не містять слова VAR. Наприклад: p>
Procedure qwerty (a, b, c: real; var
s: real); p>
Формальні
параметри, які входять до групи, що не містять слова VAR, називаються формальними параметрами-значеннями. p>
Визначення
формального параметра той чи інший спосіб істотно тільки для викликає
програми: якщо формальний параметр оголошений як параметр-змінна, то при
виклику підпрограми йому повинен відповідати фактичний параметр у вигляді
змінної певного типу; якщо формальний параметр оголошений як параметр-значення,
то при виклику йому може відповідати довільне вираження. Контроль за
неухильним дотриманням цього правила здійснює компілятором Турбо
Паскаля. p>
Для
того щоб зрозуміти, в яких випадках використовувати параметри значення, а в яких --
параметри-змінні, розглянемо, як здійснюється заміна формальних
параметрів на фактичні в момент звернення до підпрограмі. p>
Якщо
параметр визначений як параметр-значення, то перед викликом підпрограми це
значення обчислюється, отриманий результат копіюється у тимчасову пам'ять і
передається підпрограмі. Важливо врахувати, що навіть якщо в якості фактичного
параметра вказано найпростіше вираження у вигляді змінної або константи, все
одно підпрограмі буде передана лише копія змінної (константи). Таким
чином, призначення параметра-значення - передача даних з програми в
підпрограму. Якщо ж параметр визначений як параметр-змінна, то при виклику
підпрограми передається сама змінна, а не її копія. Будь-які можливі зміни
в підпрограмі параметра-значення ніяк не сприймаються що викликає
програмою, тому що в цьому випадку змінюється копія фактичного параметра, в той
час як зміна параметра-змінної приводить до зміни самого
фактичного параметра в викликає програмі. Параметр-константа схожий з
параметром-змінною: в підпрограму передається сама константа, але зміна
її неможливо. Призначення такого параметра збігається з призначенням
параметра-значення. Формальні параметри-константи вказуються в заголовку
програми після службового слова const. Його дія поширюється до найближчої точки з
комою. p>
Пояснимо
викладене. p>
..... p>
var p>
a, b: integer; p>
...... p>
procedure squar (a: integer; var b:
integer); p>
begin p>
a: = sqr (a); p>
b: = sqr (b); p>
writeln ( 'в квадраті вони виглядають
так: ', a,', ', b); p>
end; p>
........ p>
begin p>
a: = 4; b: = 6; p>
writeln ( 'уважно
подивіться на ці числа: ', a,',
', B); p>
squar (a, b); p>
writeln ( 'а так а не в
квадраті: ', a,', ', b); p>
end. p>
Результати
виглядають так: уважно подивіться на ці числа: 4, 6 p>
в квадраті вони виглядають так: 16, 36 p>
а так а не в квадраті: 4, 36 p>
Цей
приклад може служити ще й ілюстрацією механізму «закривання» глобальної
змінної а однойменної локальної: хоча мінлива оголошена як глобальна
(вона описана в зухвалому програмі перед описом процедури), в тілі
процедури її «закрила» локальна змінна а, оголошена як
параметр-значення. p>
Отже,
параметри-змінні використовуються як засіб зв'язку алгоритму, реалізованого
в підпрограмі, з «зовнішнім світом»: за допомогою цих параметрів підпрограма може
передавати результати своєї роботи викликає програмі. Зрозуміло, в
розпорядженні програміста завжди є й інший спосіб передачі результатів --
через глобальні змінні. Однак зловживання глобальними зв'язками робить
програму, як правило, заплутаною, важкою в розумінні і складною в налагодженні. У
відповідно до вимог хорошого стилю програмування рекомендується там,
де це можливо, використовувати передачу результатів через фактичні
параметри-змінні. p>
З
іншого боку, опис всіх формальних параметрів як параметрів-змінних
небажано з двох причин. По-перше, це виключає можливість виклику
підпрограми з фактичними параметрами у вигляді виразів, що робить програму
менш компактною. По-друге, і головних, в підпрограмі можливе випадкове
використання формального параметра, наприклад, для тимчасового зберігання
проміжного результату, тобто завжди існує небезпека ненавмисно
«Зіпсувати» фактичну змінну. Ось чому параметри-змінні слід
оголошувати тільки ті, через які підпрограма насправді передає
результати викликає програмі. Чим менше параметрів оголошено
параметрами-змінними і чим менше в підпрограмі використовується глобальних змінних,
тим менше небезпека отримання непередбачених програмістом побічних
ефектів, пов'язаних з викликом підпрограми, тим простіше програма в розумінні і
налагодженні. p>
Існує
одна обставина, яку слід враховувати при виборі виду формальних
параметрів. Як вже говорилося, при оголошенні параметра-значення
здійснюється копіювання фактичного параметра в тимчасову пам'ять. Якщо
цим параметром буде масив великої розмірності, то суттєві витрати
часу і пам'яті на копіювання при багаторазових зверненнях до підпрограмі
можуть стати peшающім доказом на користь оголошення такого параметра
параметром-змінною або передачі його в якості глобальної змінної. p>
Параметри масиви та параметри рядка h2>
Може
скластися враження, що оголошення змінних в списку формальних параметрів
підпрограми нічим не відрізняється від оголошення їх у розділі опису
змінних. Дійсно, в обох випадках багато спільного, але є одне істотне
відмінність: типом будь-якого параметра в списку формальних параметрів може бути
тільки стандартний або раніше оголошений тип. Тому не можна, наприклад,
оголосити наступну процедуру: p>
Procedure
S (а: array (1 .. 10] of real); p>
так
як в списку формальних параметрів фактично оголошується тип - діапазон,
вказує кордону індексів масиву. p>
Якщо
ми хочемо передати якийсь елемент масиву, то проблем, як правило, не
виникає, але якщо в підпрограму передається весь масив, то слід
спочатку описати його тип. Наприклад: p>
... ... p>
type p>
mas = array [1 .. 10] of real; p>
....... p>
PROCEDURE S (a: mas); p>
... ... p>
Оскільки
рядок є фактично своєрідним масивом, її передача в p>
підпрограму
здійснюється аналогічним чином: p>
....... p>
type p>
intype = string [15]; p>
outype = string [30]; p>
FUNCTION St (i: intype): outype: p>
Вимога
описати будь-який тип-масив або тип-рядок перед оголошенням підпрограми на
перший погляд здається несуттєвим. Дійсно, в рамках найпростіших
обчислювальних задач зазвичай заздалегідь відома структура всіх використовуваних в
програмі даних, тому статичний опис масивів не викликає проблем. Однак
розробка програмних засобів універсального призначення пов'язана зі
значними труднощами. По суті, мова йде про те, що в Турбо Паскалі
неможливо використовувати в підпрограма масиви з «плаваючими» кордонами
зміни індексів. Наприклад, якщо розроблена програма, обробна
матрицю з 10 х 10 елементів, то для обробки матриці з 9 х 11 елементів
необхідно перевизначити тип, тобто перекомпіліровать всю програму. Цей
недолік, як і відсутність у мові засобів обробки виняткових ситуацій
(переривань), успадкований з стандартного Паскаля і являє собою об'єкт
постійної і цілком заслуженою його критики. Розробники Турбо Паскаля НЕ
ризикнули кардинально змінити властивості базової мови, але, тим не менше,
включили в нього деякі засоби, що дозволяють до певної міри пом'якшити
зазначені недоліки. p>
Перш
за все, в середовищі Турбо Паскаля можна встановити режим компіляції, при якому
відключається контроль над збігом довжини фактичного і формального
параметра-рядка. Це дозволяє легко вирішити питання про передачу підпрограмі
рядки довільної довжини. При передачі рядка меншого розміру формальний
параметр буде мати ту ж довжину, що й параметр звернення; передача рядка
більшого розміру приведе до її усікання до максимального розміру формального
параметра. Слід сказати, що контроль включається тільки при передачі рядки,
оголошеної як формальний параметр-змінна. Якщо відповідний параметр
оголошений параметром-значенням, ця опція ігнорується і довжина не
контролюється. p>
Значно
складніше йде справа з передачею масивів довільної довжини. Вирішити цю
проблему за допомогою не типізованих параметрів p>
Процедурні типи h2>
Процедурні
типи - це н?? вовведеніе фірми Borland (у стандартному Паскалі таких типів немає).
Основне призначення цих типів - дати програмісту гнучкі засоби передачі
функцій і процедур в якості фактичних параметрів звернення до інших
процедур і функцій. p>
Для
оголошення процедурного типу використовується заголовок процедур, в якому
опускається її ім'я, наприклад: p>
type p>
Proc = Procedure (a, b, з: real; Var d: real); p>
Proc2 = Procedure (var a, b); p>
РгосЗ
= Procedure; p>
В
програмі можуть бути оголошені змінні процедурних типів, наприклад, так: p>
var p>
р1: Proc; p>
ар: array [1 .. N] of Proc2; p>
змінним
процедурних типів допускається привласнювати як значення імена
відповідних підпрограм. Після такого присвоювання ім'я змінної стає
синонімом імені підпрограми. p>
В
відміну від стандартного Паскаля, в Турбо Паскалі дозволяється використовувати в
переданої процедури як параметри-значення, так і параметри-змінні. p>
нетипізований параметри-змінні h2>
Ще
один і дуже корисне нововведення фірми Borland - можливість використання нетипізований
параметрів. Параметр вважається нетипізований, якщо тип формального
параметра-змінної в заголовку підпрограми не зазначений, при цьому
відповідний йому фактичний параметр може бути змінною будь-якого типу.
Зауважимо, нетипізований можуть бути тільки параметри-змінні. p>
нетипізований
параметри зазвичай використовуються у випадку, коли тип даних неістотний. Такі
ситуації найчастіше виникають різного роду копіювання одній області пам'яті в
іншу. Нетипізовані параметри дуже зручно використовувати для передачі
підпрограмі одновимірних масивів змінної довжини. p>
Параметри-складні типи даних h2>
Розглянуто
перш категорії параметрів не вичерпують всіх питань передачі інформації в Pascal-e. Використання в якості параметрів
складних типів даних має свої особливості. p>
Розглянемо
масиви та рядки відкритого типу. Відкритий масив (рядок) - масив (рядок) без
вказівки типу індексу (розміру масиву (рядки )). p>
Приклад: p>
Procedure getfive (var massiv: array
of real); p>
В
даному випадку замість формального параметра може використовуватися будь-який масив з
елементами типу real.
Індексація елементів відкритого масиву завжди починається з нуля. Такі масиви
введені для того, щоб підпрограма могла обробляти масиви будь-якого розміру. p>
Програма
обчислення x = (m! + n!)/(m + n)!,
де m, n цілі (невід'ємні) p>
program factorial_ (input, output); (назва програми) p>
label 0; (описуємо мітку) p>
var p>
rez: real; p>
m, n: longint; (описали глобальні змінні, використовувані в програмі) p>
function fact (z: longint): real;
(заголовок функції з формальним параметром-значенням, типом) p>
var p>
y: real; (описали локальну змінну) p>
begin p>
y: = 1; (для отримання
результату необхідно надати у значення 1. також за допомогою цього
реалізується обчислення 0! і 1!) p>
while z> 1 do (запускаємо цикл у зворотний бік, для
спрощення опустимо множник 1) p>
begin p>
y: = y * z; p>
z: = z-1 p>
end; p>
fact: = y (обчислюємо факторіал, присвоюємо його
значення функції) p>
end; (кінець функції) p>
begin (початок тіла програми) p>
writeln ( 'введіть невід'ємні
числа '); (для зручності користувача просимо ввести числа) p>
0: readln (m, n); (в пам'ять вводяться числа) p>
if m or n +1 do запускаємо
цикл у зворотний бік, оскільки результат виходить один і той же, але при цьому
не доводиться описувати додаткову локальну змінну для запуску циклу з
параметром. 1 виключаємо з обчислення факторіалу з вищезгаданих причин. P>
begin p>
y: = y * z; p>
z: = z-1 p>
end; p>
fact: = y цим
оператором присвоюємо функції значення факторіалу. p>
Крапку
з комою перед end
можна не ставити. p>
end; кінець функції p>
begin початок тіла програми p>
writeln ( 'введіть
невід'ємні числа '); даний оператор виводить на екран текст, укладений
між'', допомагає зрозуміти, чого ж вимагає програма. p>
0: readln (m, n); за допомогою цього оператора вводу інформації вихідні дані
заносяться до комірки пам'яті. p>
if m or n