Лекція № 6 Тема: Оператор циклу. Масиви. План заняття: Структура повторення Цикл з параметром Цикл з перед умовою Цикл з післяумовою Ітераційні цикли Одновимірні масиви Багатовимірні масиви Особливості роботи з масивами Структура повторення Для розв'язування деяких задач, доводиться багаторазово виконувати обчислення за одними й тими ж залежностями, однак для різних значень величин, що є в цих залежностях. 40 Такий процес називають циклічним. Ділянки програми, які реалізують такий процес, називаються циклами, а змінні в циклі - циклічними змінними. Алгоритм циклічної структури повинен містити такі етапи: 1) підготовку циклу - задання початкових значень змінних циклу; 2) тіло циклу - дії, що виконуються в ньому; 3) модифікацію значень змінних циклу перед кожним новим його повторенням; 4) керування циклом - перевірку умови продовження циклу і перехід на початок циклу чи вихід із циклу залежно від виконання умови. Цикл з параметром Якщо кількість повторень наперед відома, то доцільно використовувати структуру циклу з параметром, однак не обов'язково, оскільки її можна замінити іншою - наприклад, циклом з передумовою. Отже, у випадку циклу з параметром кількість повторень оператора, що виконується в циклі, не залежить від результату роботи цього оператора, її обчислюють за допомогою спеціальної змінної, яку називають параметром циклу. Для неї відоме початкове і кінцеве значення, а також крок її зміни, який задають неявно. Керування циклом відбувається шляхом порівняння поточного значення параметра циклу з кінцевим. Загальний вигляд оператора циклу з параметром такий: for <параметр_циклу>:=<вираз1> [to|downto] <вираз2> do <оператор> де <параметр_циклу> - змінна будь-якого простого типу, крім дійсного; <вираз1 > і <вираз2> - вирази, тип яких повинен збігатися з типом змінної параметра циклу; <оператор> - будь-який оператор мови Паскаль. Використовуючи оператор циклу з параметром, треба враховувати такі правила. 1. Заборонено змінювати всередині циклу, тобто в тілі циклу, значення <параметр_циклу>, <вираз1>, <вираз2>. 2. Заборонено входити в цикл, оминувши оператор for, оскільки значення <параметр_циклу>, <вираз1> і <вираз2> будуть невизначеними. 3. Цикл не виконується взагалі, якщо початкове значення більше (а у випадку downto - менше) від кінцевого. 4. Після закінчення виконання циклу значення змінної <па-раметр_циклу> не визначене і не може бути використане для подальших обчислень. 5. Після службового слова do може стояти тільки один оператор; якщо в циклі треба виконати групу операторів, то їх беруть в операторні дужки begin-end; 6. Із складеного оператора можна вийти за допомогою оператора безумовного переходу goto. У цьому випадку останнє значення <параметр_циклу> зберігається. Цикл з перед умовою Часто на практиці доводиться стикатися з циклічними обчисленнями, коли кількість повторень циклу наперед невідома, зате задана деяка умова закінчення циклу. Для таких випадків у мові Паскаль є два типи операторів - цикл з передумовою і цикл з післяумовою. Загальний вигляд оператора циклу з передумовою такий: while <умова> do <оператор>, де <умова> - це будь-який логічний вираз, <оператор> -довільний оператор мови Паскаль. Оператор виконується в циклі доти, доки умова має значення true. Як тільки значення умови стане false, відбувається вихід з циклу і виконуватиметься наступний оператор. Оператор у циклі з передумовою може не виконуватись зовсім, якщо умова дорівнює false з самого початку. Задачу обчислення мінімальної кількості членів гармонічного ряду, сума яких перевищує деяку границю, можна реалізувати за допомогою оператора циклу з передумовою: sum:=0; numb:=0; while sum<=board do begin numb:=numb+1; sum:=sum+1/numb end Цикл з післяумовою Іншим способом організації циклічного процесу, коли кількість повторень невідома, є використання оператора циклу з післяумовою. Загальний вигляд цього оператора такий: repeat <оператор 1>; <оператор 2>; <оператор п> until <умова> де <умова> - це логічний вираз; <оператор 1> ... <оператор n> -будь-які оператори мови Паскаль. Дія оператора з післяумовою подібна до дії оператора з передумовою (while), однак перевіряється умова закінчення циклу після виконання кожного циклу. Тому цикл з післяумовою виконується мінімум один раз. У ньому виконуються всі оператори, записані між словами repeat і until, які відіграють роль операторних дужок. Оператори виконуються доти, доки умова дорівнює false. Ітераційні цикли У процесі різних обчислень доводиться будувати послідовність значень gr gv ...gn, що визначаються внаслідок повторення тіла циклу. Ці значення утворюють збіжну послідовність, що прямує до деякої границі а lim дп = а. n->~ Це, звичайно, цикли з невідомою наперед кількістю повторень. Кожне наступне значення послідовності обчислюється через попереднє gn-1, і з урахуванням збіжності є точнішим наближенням до результату, тобто границі а. Цикли, що реалізують таку послідовність наближень, називаються ітерацій-ними. Умова продовження (чи закінчення) в ітераційних циклах ґрунтується на властивості безмежного наближення елементів послідовності до границі а. Ітераційний цикл закінчуєтся, коли для деякого п виконується умова abs (gт-gт-1) <= е, де е- допустима похибка обчислень. Одновимірні масиви Масив - це впорядкований набір даних однакового типу. Приклади масивів: рядок тексту, компонентами якого є окремі символи; вектор, що є масивом дійсних чисел; матриця, як масив векторів. Кожному простому значенню, що є в масиві, тобто кожному компонентові відповідає сукупність номерів, які визначають місце його в загальній послідовності. Ці номери називають індексами. Головні характеристики сукупності значень, що утворюють масив, такі: ім'я, розмірність (тобто кількість компонентів), тип компонентів і тип індексів, їм 'я - це повна змінна типу масив, її значенням є весь масив. Загальна форма опису масиву така: var х, у, v: array [1..10] of real; Можливий і такий опис: s: array [1147..1999] of integer; r: array [-754..-1] of integer; тобто від'ємні числа обмежують діапазон. Як тип індексу, крім діапозону integer і перелічуваного типу, можна використовувати типи boolean і char, як упорядковані. Окремий компонент масиву вибирають, зазначаючи ідентифікатор масиву, після якого в квадратних дужках записують індексний вираз. Індексний вираз повинен набувати значення, що є в діапазоні, визначеному типом індексу. Наприклад, для описаних вище типів змінних можна писати, визначивши наперед: і:=5; j:=2; v[i-j]:=7.5; c[sr]:=false; z[pred(nd)]:=c[sb]; Ім'я з індексами в квадратних дужках - це часткова змінна, оскільки її значенням є не весь масив, а його окремий компонент. Багатовимірні масиви Оскільки, як зазначено, тип компонента масиву довільний, то він може бути й масивом. У результаті одержують багатовимірний масив. Приклад опису такого масиву: var М: array [А..В] of array [C..D] of T; де Т - раніше описаний тип (або стандартний). Тоді j-й компонент (типу Т) i-го компонента масиву М матиме вигляд M[i][j]. Частіше для багатовимірних масивів використовують скорочену форму опису var М: array [A..B, C..D] of T; а компоненти позначають M[i,j]. Сталі, що визначають тип індексів масиву у разі його опису (тут А,В,С, D), потрібно визначити перед їхнім застосуванням для опису масиву. Наведений приклад є прикладом двовимірного масиву. Однак Т також може мати тип масиву. Якщо задано п типів індексів, то масив називається n-вимірним. Особливості роботи з масивами У випадку, коли змінні А і В є масивами тотожного типу, то присвоєння А:=В можливе, якщо масиви допускають покомпонентне присвоєння А[і]:=В[і] для всіх і. Таке присвоєння є скороченим записом покомпонентного присвоєння. Для задания значень елементів масиву, крім операторів присвоєння, можна використати оператори введення даних. У мові Паскаль для введення і виведення масивів застосовують поелементне введення і виведення, коли вводять і виводять окремі елементи масиву. Наприклад: program vvid; var v: array [1..3] of integer;; mas: array [1..2, 1..3]; i,j: integer; begin read(v[1], v[2], v[3]); for i:=1 to 2 do forj:=1 to 3 do read(mas[i,j]); {виведення масивів} for i:=1 to 3 do writeln(v[i]:5); for i:=1 to 2 do begin writeln; for j:=1 to 3 do write(mas[i,j]:4); end end. Під час роботи з масивами найчастіше виникають помилки, пов'язані з виходом індекса за допустимі межі. Частину таких помилок виявляє компілятор. Наприклад: var М: array [1..8] of real; М[9]:=1.1; Однак якщо індекс є змінною, а не сталою, то ця помилка виникає на етапі виконання програми. Під час транслювання компілятор вставляє в об'єктний код динамічні перевірки на належність поточних значень індексів допустимому діапазонові. Ці перевірки збільшують розмір об'єктного коду, проте роблять програму надійною.