Лабораторна робота N9 Робота з даними комбінованого типу. Оголошення та використання модулів. МЕТА РОБОТИ Навчитися використовувати у програмах структуровані данi та власні модулі. ПОРЯДОК ВИКОНАННЯ РОБОТИ При підготовці до лабораторної роботи, згідно із індивідуальним завданням, розробити алгоритм та програму на мові Pascal, в яких використовуються структуровані данi. Основні обчислення оформити у вигляді окремого модуля. Виконати ввід, виконання та відлагодження програми і модуля. Проаналізувати отримані результати та оформити звіт по роботі. IНДИВIДУАЛЬНI ЗАВДАННЯ 1. Заданий масив записiв з iнформацiєю про успiшнiсть групи студентiв по дисциплiнi програмування: прiзвище, iм'я, по-батьковi, оцiнка: знайти середнiй бал групи по цiй дисциплiнi; 2. Заданий масив записiв з iнформацiєю про успiшнiсть групи студентiв по дисциплiнi програмування: прiзвище, iм'я, по-батьковi, оцiнка: вивести на друк прiзвища студентiв, якi мають незадовiльнi оцiнки. 3. Вiдомостi про автомобiль складаються iз його марки, номера,кольору, прiзвища власника: пiдрахувати кiлькiсть автомобiлiв заданої марки; 4. Вiдомостi про автомобiль складаються iз його марки, номера, кольору, прiзвища власника: пiдрахувати кiлькiсть автомобiлiв кожної марки; 5. Заданий масив записiв з iнформацiєю про продукцiю пiдприємства: назва виробу, код виробу, кiлькiсть, цiна: впорядкувати цей масив по зростанню коду виробу; 6. Заданий масив записiв з iнформацiєю про продукцiю пiдприємства: назва виробу, код виробу, кiлькiсть, цiна. Впорядкувати цей масив по спаданню коду виробу та його цiни. Тобто, якщо маємо два товари з однаковою цiною то такi товари розташовуються по спаданню коду. 7. Сформувати масив записiв з iнформацiєю про успiшнiсть студентiв по 5-ти предметах: знайти середнiй бал кожного студента; 8. Сформувати масив записiв з iнформацiїю про успiшнiсть студентiв по 5-ти предметах:вивести на друк прiзвища студентiв iз середнiм балом бiльшим або рiвним 4. 9. У масивi записiв приведена iнформацiя про студентiв факультету: прiзвище, iм'я, по-батьковi, стать, вiк, курс, група, оцiнки по 5-ти предметах. Написати програму, яка виводить найбiльш розповсюдженi жiночi iмена; 10. У масивi записiв приведена iнформацiя про студентiв факультету: прiзвище, iм'я, по-батьковi, стать, вiк, курс, група, оцiнки по 5-ти предметах. Написати програму, яка виводить найбiльш розповсюдженi чоловiчi iмена; 11. Записна книжка з телефонами може бути оголошена наступним чином: type word_= packed array [1..9] of char; tel_number = 100000 ..999999; p=record name : word_; number : tel_number end; page=array [1..20] of p; tel_book=array ['A'..'Z'] of page; Вважаючи, що на кожнiй сторiнцi записної книжки вказанi прiзвища, що починаються з однiєї й тiєї ж букви, написати функцiю,яка визначає чи є у записнику вiдомостi про знайомого з заданим прiзвищем,i, якщо є, вивести його номер телефона; 12. Написати процедуру, яка обчислює значення квадратного трьохчлена ах^2+ вх+ с з комплексними коефiцiентами а, в, с в комплекснiй точцi х: type сomplex=record re, im: real end; 13. Шахматне поле може бути оголошене наступним чином: type поле = record vert:(а, в, с, d, e, f, g, h); gorz: 1..8 end; Написати логiчну функцiю hid_ferzya (n1, n2), яка перевiряє, чи ферзь за один хiд перейде з позицiї n1 у позицiю n2 (позицiї n1 та n2 мають тип "поле"). 14. Написати процедуру Dec_Pole (d,p), яка перетворю' координати точки на площинi iз декартових d в полярнi p координати, i процедуру Pole_Dec(p,d), яка виконує зворотнє перетворення. Необхiднi типи даних: type Decart= record x,y : real end; Polyar = record r,fi: real end; {r>=0, - П<=fi<=П}. 15. У масивi записiв задана iнформацiя про книги бiблiотеки: автор, назва, рiк видання, код тематики, цiна. Вивести на екран iнформацiю про книги, виданi пiсля 1991 року для заданого автора; МЕТОДИЧНI ВКАЗIВКИ. МОДУЛI Директива uses. Директива uses iдентифiкує всi модулi, що використовуються програмою, включаючи безпосередньо модулi, що використовуються i модулi, що використаються цими модулями. Модуль System (в Delphi це SysUtils)завжди використовується автоматично. System реалiзує весь нижнiй рiвень, пiдтримку програм часу виконання для пiдтримки таких засобiв, як файловий ввiд/вивiд, обробка рядкiв, операцiї з плавачою комою, динамiчний розподiл пам'ятi i iнших. Порядок перерахування модулей в uses визначає порядок їх інiцiалiзацiї. Cинтаксис модулiв. Модулi в Pascal є основою модульного програмування. Вони використовуються для створення бiблiотек, що можуть включатися в рiзноманiтнi програми (при цьому стає необов'язковим мати в наявностi вхiдний код), а бiльшi програми можуть подiлятися на логiчно зв'язанi модулi. Iм'я модуля використовується при зсиланнi на модуль в uses. Це iм'я повинно бути унiкальним, бо два модуля з одним iм'ям не можуть використовуватися водночас. Unit USRec; Інтерфейсний роздiл. В інтерфейсному роздiлi оголошуються тi константи, типи, змiннi, процедури i функцiї, що є глобальними, тобто є доступними основнiй програмi (програмi або модулю, що використовують даний модуль). Основна програма має доступ до цих елементiв, як якщо б вони були б проголошенi в блоку, що включає головну програму. Тiла процедур i функцiй знаходяться в роздiлi реалiзацiї. Interface Const n=25; Type inf = record Name:string; Code:word; Count:word; Price:real; end; InfVect=array[1..n] of inf; Procedure ReadVect(Var v:InfVect;m:word); Procedure WriteVect(Var v:InfVect;m:word); Procedure SortByCode(Var v:InfVect;m:word); Procedure SortByPrice(Var v:InfVect;m:word); Procedure FormLessThenPrice(Var v:InfVect;m:word;p:real; Var x:InfVect;Var k:Word); Роздiл реалiзацiї. В роздiлi реалiзацiї визначаються тіла всiх глобальних процедур i функцiй. В ньому також описуються константи, типи, змiннi, процедури i функцiї, що є локальними, тобто є недосяжними основнiй програмi. По механiзму чинностi оголошення процедур i функцiй в інтерфейсному роздiлi аналогiчнi forward оголошенню, хоча директива forward не вказується. Таким чином, цi процедури i функцiї можуть бути визначенi (i до них можна звертатися в будь-якій послiдовностi) в роздiлi реалiзацiї. Примiтка: . Заголовки процедур i функцiй можуть бути здубльованi з інтерфейсного роздiлу. Необов'язково задавати список формальних параметрiв, але якщо ви зробили це, то в випадку невiдповiдностi оголошення в інтерфейсному роздiлi i роздiлi реалiзацiї компiлятор видасть помилку часу компiляцiї. Роздiл iнiцiалiзацiї. Роздiл iнiцiалiзацiї є останнiм роздiлом модуля. Вiн може складатися або з зарезервованого слова end (в цьому випадку модуль не мiстить коду iнiцiалiзацiї), або з операторної частини, що повинна виконуватися для iнiцiалiзацiї модуля. Роздiли iнiцiалiзацiї модулiв, що використовуються програмою, виконуються в тому же порядку, в якому модулi вказанi в оголошенні. uses. Implementation Procedure ReadVect(Var v:InfVect;m:word); var i:word; begin for i:=1 to m do begin Writeln('Введiть данi про ',i,'-й вироб:'); Write('Введiть назву '); Readln(v[i].Name); Write('Введiть код '); Readln(v[i].Code); Write('Введiть к-ть '); Readln(v[i].Count); Write('Введiть цiну '); Readln(v[i].Price); end; end; Procedure WriteVect(Var v:InfVect;m:word); var i:word; begin for i:=1 to m do begin Writeln('Данi про ',i,'-й вироб:'); Write('назва '); Write(v[i].Name); Write(' код '); Write(v[i].Code); Write(' к-ть '); Write(v[i].Count); Write(' цiна '); Writeln(v[i].Price:1:2); end; end; Procedure SortByCode(Var v:InfVect;m:word); var i,j:word; temp:inf; begin for i:=1 to m do for j:=1 to m-i do if V[j].Code>V[j+1].Code then begin temp:=V[j+1]; V[j+1]:=V[j]; V[j]:=temp; end; end; Procedure SortByPrice(Var v:InfVect;m:word); var i,j:word; temp:inf; begin for i:=1 to m do for j:=1 to m-i do if V[j].Price>V[j+1].Price then begin temp:=V[j+1]; V[j+1]:=V[j]; V[j]:=temp; end; end; Procedure FormLessThenPrice(Var v:InfVect;m:word;p:real; Var x:InfVect;Var k:Word); var i:word; begin k:=0; for i:=1 to m do if V[i].Price<p then begin k:=k+1; X[k]:=V[i]; end; end; Побiчнi зсилання на модулi, що використовуються. В описі uses в програмi або модулi вказуються iмена тiльки тих модулiв, що явно використовуються цим модулем (або програмою). Розглянемо наступний приклад: program Prog; uses Unit2; const a=b; begin end. unit Unit2; interfase uses Unit1; const b=c; implementation end. unit Unit1; interfase const c=1; implementation const d=2; end. У наведеному вище прикладi Unit2 явно залежить вiд Unit1, а Prog явно залежить вiд Unit2. Бiльше того, Prog неявно залежить вiд Unit1 (через Unit2), хоча жоден з iдентифiкаторiв, проголошених в Unit1,недосяжний Prog. Щоб відкомпiлюати модуль, Turbo Pascal повинен знайти всi модулi,вiд яких цей модуль залежить (явно або неявно). Так, щоб вiдкомпiлювати Prog, компiлятор повинен знайти Unit1 i Unit2, в протилежрому випадку вiдбудеться помилка. Коли в iнтерфейсну частину модуля вносяться модифiкацiї, iншi модулi, що використовують цей модуль, повиннi бути ще раз вiдкомпiльованi. Однак, якщо модифiкацiя торкнулися тiльки роздiлу реалiзацiї або роздiлу iнiцiалiзацiї, то iншi модулi,в яких використовується цей модуль, перекомпiльовувати не потрiбно. В попередньому прикладi, якщо інтерфейсна частина модуля Unit1 змiнювалася (наприклад с=2), то модуль Unit2 потрiбно перекомпiлювати. Модифiкацiя ж роздiлу реалiзацiї (наприклад, D=1) не вимагає перекомпiляцiї Unit2. При компiляцiї модуля в Turbo Pascal на основi контрольної суми интерфейсного роздiлу обчислюється номер версiї модуля. В попередньому прикладi при компiляцiї модуля Unit2 в вiдкомпільованiй версiї модуля Unit2 зберiгається номер версiї модуля Unit1. При компіляцiї основної програми номер версiї модуля Unit1 порiвнюється з номером версiї,збереженим в модулi Unit2. Якщо номери версiй не спiвпадають, що свiдчить про модифiкацiю в интерфейснiй частинi модуля Unit1 з часу останньої компіляцiї модуля Unit2, то компiлятор, в залежностi вiд режиму компіляцiї, видає повiдомлення про помилку або перекомпiльовує модуль Unit2. Розглянемо ще раз приклад використання модулiв: Заданий масив записів з інформацією про продукцію підприємства: Назва виробу, код виробу, кількість, ціна. а)впорядкувати цей масив по зростанню коду виробу; б)впорядкувати цей масив по зростанню ціни віробу; в)сформувати новий масив,вибрати в нього записи з ціною меншою заданої. Unit USRec;{ Унiкальне iм'я модуля } Interface{ iнтерфейсний роздiл} Const n=25; Type inf = record {опис типу запису} Name:string; Code:word; Count:word; Price:real; end; InfVect=array[1..n] of inf; { опис вектора з записiв} {процедури для роботи з вектором} Procedure ReadVect(Var v:InfVect;m:word); Procedure WriteVect(Var v:InfVect;m:word); Procedure SortByCode(Var v:InfVect;m:word); Procedure SortByPrice(Var v:InfVect;m:word); Procedure FormLessThenPrice(Var v:InfVect;m:word;p:real; Var x:InfVect;Var k:Word); Implementation {роздiл релiзацiї} Procedure ReadVect(Var v:InfVect;m:word);{процедура читання вектору} var i:word; begin for i:=1 to m do begin Writeln('Введiть данi про ',i,'-й вироб:'); Write('Введiть назву '); Readln(v[i].Name); Write('Введiть код '); Readln(v[i].Code); Write('Введiть к-ть '); Readln(v[i].Count); Write('Введiть цiну '); Readln(v[i].Price); end; end; Procedure WriteVect(Var v:InfVect;m:word);{ процедура виводу вектора} var i:word; begin for i:=1 to m do begin Writeln('Данi про ',i,'-й вироб:'); Write('назва '); Write(v[i].Name); Write(' код '); Write(v[i].Code); Write(' к-ть '); Write(v[i].Count); Write(' цiна '); Writeln(v[i].Price:1:2); end; end; Procedure SortByCode(Var v:InfVect;m:word);{ сортування по коду} var i,j:word; temp:inf; begin for i:=1 to m do for j:=1 to m-i do if V[j].Code>V[j+1].Code then begin temp:=V[j+1]; V[j+1]:=V[j]; V[j]:=temp; end; end; Procedure SortByPrice(Var v:InfVect;m:word);{ сортування по цiнi} var i,j:word; temp:inf; begin for i:=1 to m do for j:=1 to m-i do if V[j].Price>V[j+1].Price then begin temp:=V[j+1]; V[j+1]:=V[j]; V[j]:=temp; end; end; Procedure FormLessThenPrice(Var v:InfVect;m:word;p:real; Var x:InfVect;Var k:Word); { формування нового з цiною меншою за задану } var i:word; begin k:=0; for i:=1 to m do if V[i].Price<p then begin k:=k+1; X[k]:=V[i]; end; end; End. Program SortRec;{ головна програма } Uses USRec;{ використання орiгiнального модуля USRec } Var V,X:InfVect;{вектори з записiв} m,k:word; flag:1..4; p:real; Begin { формування масиву} Write('Введiть к-ть елементiв в масивi '); Readln(m); Writeln('Введiть масив з ',m,' елементiв'); ReadVect(V,m); { головний цикл програми} repeat {вибiр одної з опцiй} Writeln; Writeln('1 - Впорядкуваня по зростаню коду виробу'); Writeln('2 - Впорядкуваня по зростаню цiни виробу'); Writeln('3 - Формуваня нового масиву з цiною меньшою заданої'); Writeln('4 - Вихiд'); Write('Ваш вибiр:'); Readln(flag); case flag of 1:SortByCode(V,m); { сортуїмо по коду } 2:SortByPrice(V,m); { сотуїмо по цiнi } 3:begin Write('Введiть цiну:'); Readln(p); FormLessThenPrice(V,m,p,X,k); { формуємо новий масив з цiною меншою за задану} Writeln('Сформовано новий масив:'); WriteVect(X,k) { виводимо вектор} end; end; if flag in [1,2] then WriteVect(V,m); { виводимо вектор} until flag=4{поки не вибрано пункт вихiд} End.