МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів
Контакти
Тлумачний словник Авто Автоматизація Архітектура Астрономія Аудит Біологія Будівництво Бухгалтерія Винахідництво Виробництво Військова справа Генетика Географія Геологія Господарство Держава Дім Екологія Економетрика Економіка Електроніка Журналістика та ЗМІ Зв'язок Іноземні мови Інформатика Історія Комп'ютери Креслення Кулінарія Культура Лексикологія Література Логіка Маркетинг Математика Машинобудування Медицина Менеджмент Метали і Зварювання Механіка Мистецтво Музика Населення Освіта Охорона безпеки життя Охорона Праці Педагогіка Політика Право Програмування Промисловість Психологія Радіо Регилия Соціологія Спорт Стандартизація Технології Торгівля Туризм Фізика Фізіологія Філософія Фінанси Хімія Юриспунденкция |
|
|||||||||||
Параметри - значенняType End Begin End Begin Begin Begin Begin Begin Begin Begin Begin Begin Begin Begin Begin Begin Тип запис End. Begin Repeat Begin clrscr; nath:=[1..n]; kin:=[]; next:=2; whilenot(next in nath)do inc(next); kin:=kin+[next]; j:=next; whilej<=ndo nath:=nath-[j]; j:=j+next; end; untilnath=[]; forj:=2tondo ifj in kinthenwrite(j:5);
Тип запис, також як і масив, є структурованим типом даних, тобто таким, змінні якого складені з декількох частин. У Турбо-Паскале існує можливість об'єднати в одній змінній дані різних типів (тоді як у масиві всі елементи мають однаковий тип). Приведемо приклад такого типу. Нехай у змінній потрібно зберігати відомості про деяку людину: ПІБ, стать, адреса, телефон. Тоді для збереження цих даних буде зручний такий тип: type tPerson = record Name,Surname,SecondName: string[30]; Male: boolean; Address: string; Phone: longint; end;
Оголошення змінної типу запис виконується стандартно, за допомогою var. Частини запису (у нашому випадку: Name, Surname, SecondName, Male, Address, Phone) називаються полями. Звертання до поля запису в програмі виконується за допомогою знака ‘.’ (крапка). Приклад звертання до полів: var p: tPerson; ... ... p.Surname:='Іванов'; p.Name:='Іван'; p.SecondName:=’Іванович’; ... if (p.Phone<0) or (p.Phone>999999) then writeln(‘Помилка’); ... end.
Помітимо, що в цьому прикладі постійно приходиться звертатися до полів однієї і тієї ж змінної типу запис, і, отже, постійно писати її ім'я. Існує можливість позбутися від цієї незручності. У Турбо Паскалі є оператор приєднання (with), що дозволяє один раз указати, яким записом ми користаємося і надалі писати лише імена полів. Цей оператор має такий вигляд: with <ім'я_запису> do <оператор>; Найчастіше як оператор використовується складений оператор. Приклад: with p do begin Surname:=' Іванов'; Name:=’Іван’; ... end;
Записи можна включати до складу більш складних змінних, наприклад масивів і інших записів. При необхідності збереження інформації про співробітників деякої організації може виявитися корисним масив:
const N = 30; type tStaff = array [1..N] of tPerson;
Розглянемо інший приклад, де ілюструється використання вкладених записів. Нехай прямокутник визначається координатами точки, що є його лівим верхнім кутом, шириною, висотою і кольором ліній. На Турбо Паскалі ці відомості можна об'єднати в такий запис:
type tPoint = record x,y: integer; end;
tRectangle = record LeftTop: tPoint; Width, Height: integer; Color: integer; end;
Для такого запису можна застосовувати ще одну форму оператора with, що може «приєднувати» кілька імен записів, наприклад:
varrect: tRect; with rect, LeftTop do begin x:=100; y:=150; Color:=11; ... end;
Без використання with з'явилися б вирази виду rect.Color, rect.LeftTop.x, rect.LeftTop.y і т.п. Покажемо тепер, як можна використовувати масиви усередині записів. Припустимо, що потрібно зберігати інформацію вже не про прямокутник, а про довільний багатокутник. У цьому випадку буде потрібно задати кількість точок у ньому і список усіх цих точок, тобто масив. Потрібно передбачити можливість збереження відомостей про багатокутники з різним числом вершин, тому зробимо масив досить великим, а реальне число вершин будемо зберігати в окремому полі запису. Усе це буде виглядати так:
const MaxVertex = 200;
type tPolygon = record size: integer; V: array [1..MaxVertex] of tPoint; Color: tColor; end;
Існує різновид записів, що містить так називану варіантну частину. Для кращого розуміння розглянемо їх на прикладі. Нехай запис повинний зберігати повну інформацію про геометричну фігуру: колір, положення і розміри (для окружності — координати центра і радіус, для прямокутника — координати лівої верхньої і правий нижньої вершин, для квадрата — координати лівої верхньої вершини і довжина сторони). У принципі, можна було б включити в запис усі перераховані вище поля, але в такому випадку більшість з них часто залишалися б незайнятими, тому зручніше буде таке рішення: type tFKind = (fCir,fRect,fSqr); tFigure = record Color: integer; case kind: tFKind of fCir: (Center: tPoint; r: integer); fRect: (LeftTop,RightBottom: tPoint); fSqr: (LT: tPoint; size: integer); end; У цьому записі мається одне звичайне поле (Color), а інші 6 і являють собою варіантну частину. Для кола в ній є поля Center і r, для прямокутника — LeftTop і RightBottom, для квадрата — LT і size. Фраза kind: tFKind не є обов'язкової, вона служить для розуміння того, які поля до яких фігур відносяться. Можна написати просто case integer of ... і нумерувати варіанти цілими числами. Помітимо також, що в оголошенні нашого запису немає слова end, що відноситься до case.
Ми можемо звертатися до будь-якого поля варіантної частини, однак варто пам'ятати, що при записі даних у поле для однієї фігури поля для інших фігур можуть змінитися. Щоб зрозуміти, чому так відбувається, досить розглянути спосіб збереження змінної типу tFigure: З малюнка видно, що варіантна частина зберігається в одній частині пам'яті, тобто поля можуть накладатися один на одного.
Процедури і функції Процедура ( послідовність дій (записаних на Паскалі), названа яким-небудь ім'ям. Для того щоб виконати цю послідовність, потрібно у відповідному місці програми вказати її ім'я (так, наприклад, для очищення екрана при роботі з графікою ми вказуємо ClearDevice;). Крім того, що програма стає при використанні процедур коротше і зрозуміліше, процедури можна викликати з різних місць програми (у противному випадку довелося б повторювати в тексті програми однакові послідовності дій кілька разів). Ті дії, що входять у процедуру, записуються до початку основної програми в наступному виді:
program ... const ... type ... var ... procedure MyProc; {дії} end; {основна програма} end.
Розглянемо приклад знаходження максимуму з трьох чисел: program Max1; var a,b,c,m: integer; write('Введіть a: '); readln(a); write('Введіть b: '); readln(b); write('Введіть c: '); readln(c); if a>b then m:=a else m:=b; if c>m then m:=c; writeln('Максимум = ',m); readln; end. Перепишемо його з використанням процедури: program Max2; var a,b,c,m: integer; procedure FindMax; if a>b then m:=a else m:=b; if c>m then m:=c; end; write('Введіть a: '); readln(a); write('Введіть b: '); readln(b); write('Введіть c: '); readln(c); FindMax; writeln('Максимум = ',m); readln; end. Цей варіант можна покращити. Поки наша процедура може шукати мінімум тільки серед значень конкретних змінних a, b і c. Змусимо її шукати мінімум серед будь-яких трьох цілих чисел і поміщати результат у потрібну нам змінну, а не завжди в m. Щоб була видна користь від такої процедури, розглянемо приклад програми для пошуку максимуму серед чисел a+b, b+c і a+c: program Max3; var a,b,c,m: integer; procedure FindMax(n1,n2,n3: integer; var max: integer); if n1>n2 then max:=n1 else max:=n2; if n3>max then max:=n3; end; write('Введіть a: '); readln(a); write('Введіть b: '); readln(b); write('Введіть c: '); readln(c); FindMax(a+b,b+c,a+c,m); writeln('Максимум із сум = ',m); readln; end. У дужках після імені процедури (у її описі) записані так називані параметри. Цей запис означає, що усередині процедури можна використовувати цілі числа, позначені n1, n2 і n3, а також заносити значення в змінну типу integer, що усередині процедури називається max (а реально під час роботи програми всі дії виконуються над змінною m). Параметри, у яких зберігаються числа (n1,n2,n3) називаються параметрами-значеннями; а ті, котрі позначають змінні (max) – параметрами-змінними, перед ними в описі ставиться слово var. Параметри, на які маються посилання усередині процедури (n1, n2, n3, max), називаються формальними, а ті, котрі реально використовуються при виклику (a+b, b+c, a+c, m) — фактичними. Процедури останнього виду виявляються досить зручними. Можна один раз написати таку процедуру, переконатися в її працездатності і використовувати в інших програмах. Прикладами таких процедур є процедури для роботи з рядками, убудовані в Турбо-Паскаль. У нашому прикладі можна переписати програму і по-іншому. Максимум із трьох чисел визначається по них однозначно, чи, говорячи математичною мовою, є функцією цих трьох чисел. Поняття функції є також і в Паскале. Розглянемо таку програму: program Max4; var a,b,c,m: integer; function Max(n1,n2,n3: integer) : integer; var m: integer; if n1>n2 then m:=n1 else m:=n2; if n3>m then m:=n3; Max:=m; end; write('Введіть a: '); readln(a); write('Введіть b: '); readln(b); write('Введіть c: '); readln(c); writeln('Максимум = ',Max(a+b,b+c,a+c)); readln; end. Нам уже відомо як викликати функцію з програми (наприклад sqrt, sin і т.п.). Розглянемо опис функції. Він дуже схожий на опис процедур, але є дві відмінності: 1. Після імені функції у списку параметрів (якщо є) через двокрапку записується тип значення функції (можливі не тільки числові типи, але і логічні, строкові, символьні); 2. Серед операторів у тілі функції найбільш важливими є оператори присвоювання значення функції (у нашому випадку це рядок Max:=m;). У записаній вище функції використовується так називана локальна змінна m, тобто змінна, котра «видна» тільки нашій функції, а інші процедури і функції, а також головна програма її «не бачать». Крім локальних змінних у Турбо-Паскалі можна визначати локальні константи і типи.
Приведемо інші приклади процедур і функцій. 1. Напишемо на Паскале функцію . function Cube(x: real): real; Cube:=x*x*x; end;
2. Обчислення площі трикутника через довжини сторін. Тут буде використана формула Герона: , де p – напівпериметр трикутника, a, b, c – довжини сторін. function Square(a,b,c: real): real; var p: real; p:=(a+b+c)/2; Square:=sqrt(p*(p-a)*(p-b)*(p-c)); end;
3. Процедура для рішення квадратного рівняння. Будемо передавати цій процедурі коефіцієнти рівняння, а результати своєї роботи вона буде видавати в трьох параметрах-змінних. Через першу, логічного типу, процедура повідомить, чи є дійсні корені, а ще в двох вона видасть самі ці корені (якщо коренів нема, то на ці дві змінні користувач нашої процедури може не звертати уваги). procedure SqEquation(a,b,c: real; var RootsExist: boolean; var x1,x2: real); var d: real; d:=sqr(b)-4*a*c; if d>=0 then begin RootsExist:=true; x1:=(-b+sqrt(d))/(2*a); x2:=(-b-sqrt(d))/(2*a); else RootsExist:=false; end; Можна замість процедури написати і функцію, за логічним значенням якої ми визначаємо, чи є корені, а самі корені передавати також як і в процедурі: function EqHasRoots(a,b,c: real; var x1,x2: real) : boolean; var d: real; d:=sqr(b)-4*a*c; if d>=0 then begin EqHasRoots:=true; x1:=(-b+sqrt(d))/(2*a); x2:=(-b-sqrt(d))/(2*a); else EqHasRoots:=false; end; Використовувати таку функцію навіть простіше чим останню процедуру: if EqHasRoots(1,2,1,r1,r2) then writeln(r1,' ',r2) else writeln('Немає коренів'); Формальні і фактичні параметри. Механізм параметрів У заголовку процедури чи функції, як ми вже знаємо, може міститися список параметрів. Параметри являють собою ідентифікатори змінних і служать для обміну значеннями між підпрограмою і викликаючою її програмною одиницею. При цьому в описі підпрограми, оскільки він включається в текст програми один раз, імена параметрів вибираються певним чином і безвідносно до імен змінних які використовуються в інших частинах програми. Такі параметри, імена яких зазначені в заголовку підпрограми, називаються формальними. З іншого боку, при кожному новому зверненні до підпрограми в неї можуть передаватися значення різних змінних. Такі змінні, імена яких підставляються в оператор виклику підпрограми при фактичному звертанні до неї, називаються фактичними параметрами. При виклику процедури чи функції кількість і тип фактичних параметрів повинні відповідати кількості і типу формальних параметрів. З останнього, утім, є виключення. Список формальних параметрів указується після імені підпрограми і заключається в круглі дужки. Опис формальних параметрів дуже схожий на опис змінних у блоці. Кожен параметр, заданий у заголовку вважається локальним у даній підпрограмі так само, як і змінні, описані в блоці цієї підпрограми. Ідентифікатори формальних параметрів можна вважати умовними позначеннями в тілі підпрограми тих реальних чи ФАКТИЧНИХ параметрів, що будуть передані в підпрограму при її виклику. Нижче приводяться синтаксичні діаграми для формальних параметрів. Приклади заголовків процедур і функцій: function MaxElem ( A:Vector; n=byte ): real; Procedure Sum (А,В:Matrix; var С:Matrix ); Procedure Move ( var Source, Dest; n : word); Слід звернути увагу на декілька обставин. По-перше, типи формальних параметрів повині обов’язково позначатись ідентифікаторами. Наприклад, наступний заголовок є неприпустимим: Procedure Incorrect ( var A : array[1..10] of byte ) Якщо необхідно передати в підпрограмму параметр із типом, який визначає програміст, слід скористатись його ідентифікатором, наприклад: MyArray = array[1..10] of byte; procedure Correct ( var A : MyArray ) ; Таке обмеження має пряме відношення до питань еквівалентності типів Справді, іменна еквівалентність типів, прийнята в мові Pascal, приведе до того, що явне завдання типу формального параметра виключить можливість зіставлення його з будь-яким типом фактичного параметра, навіть якщо обидва цих типа будуть описані однаково. Із приведених вище синтаксичних діаграм випливає, що в списку формальних параметрів підпрограм припустимі принаймні три способи їхнього завдання: 1. Параметри, перед якими відсутнє службове слово var і за якими вказаний ідентифікатор типу. 2. Параметри, перед якими є службове слово var і за яким стоїть тип. 3. Параметри, перед якими є службове слово var після якого не вказаний тип. Ці три способи завдання формальних параметрів відображають три різних способи передачі параметрів. перший спосіб називається передачею параметрів за значенням, другий спосіб - передачею параметрів по посиланню, третій спосіб передачею не типізованих параметрів по посиланню. Одна підпрограма може одержувати різні параметри всіма трьома способами одночасно. Перші два способи передачі параметрів (ці параметри також називаються параметрами-значеннями і параметрами-змінними) були визначені в авторській версії мови Pascal, третій спосіб мається тільки в Turbo Pascal і являє деякий відступ від принципів строгої типізації, характерних для мови. Це найбільш поширений і найпростіший спосіб передачі параметрів. У даному випадку параметр вважається звичайною локальною змінною у межах підпрограми, з тією особливістю, що при виклику підпрограми початкове значення параметра автоматично встановлюється рівним значенню відповідного фактичного параметра, заданого при виклику підпрограми. Цей фактичний параметр може бути довільним виразом того ж типу, що і формальний параметр. Усередині підпрограми можливі довільні дії з даним формальним параметром, але будь-які зміни його значення НІЯК НЕ ВІДБИВАЮТЬСЯ на значеннях змінних поза підпрограмою. Нижче приводиться приклад процедури, що використовує передачу параметрів за значенням. procedure SumSquare ( X, У : real ) ; begin x := x*x; Y := Y*Y; Writeln('Сума квадратів = ',X+Y) end; Виклик цієї процедури може відбуватись так: Читайте також:
|
||||||||||||
|