Вирази і оператори Delphi
У програмах Delphi застосовуються
- математичні вирази
- логічні вирази
- вираження з рядками
та інші.
Математичні вирази
У математичних виразах використовуються операції присвоювання :=, додавання +, віднімання -, множення * , ділення /, цілочисельного ділення div, залишку від ділення mod. При використанні цих операцій важливий пріоритет їх виконання, так як в програмуванні на мові Delphi, як і в звичайній математиці, вирази виконуються не в порядку проходження, а з урахуванням пріоритету. У операцій множення і ділення вищий пріоритет, ніж у операцій додавання і віднімання .
Тобто, результат виразу
X:=1+2*3-4/5;
буде дорівнювати не 1, як у випадку послідовного виконання, а 6.2.
Якщо ж ми хочемо отримати саме послідовне виконання, то необхідно застосовувати дужки () , відокремлювалися ті операції, які необхідно виконати першими. Дужки можуть бути вкладені одна в одну необмежену кількість разів:
X:=((1+2)*3-4)/5;
Ось тепер X
буде дорівнює 1.
Крім чотирьох математичних дій в Delphi є безліч математичних функцій, таких, наприклад, як тригонометричні, логарифмічні, і т.д. Вони стають доступні в програмі після додавання в секцію Interface uses модуля Math . Їх опис також можна знайти в модулі Math.pas (можна знайти скориставшись пошуком Windows). Багато з них можна реалізувати і самому, але вбудовані функції напевно будуть працювати швидше і краще, тому що написані на мові асемблера.
Логічні вирази
Логічні вирази виконуються над операндами логічного типу, тобто мають тип Boolean Delphi. Вони застосовуються в основному в умовних операторах.
Оператори Delphi
Для створення додатків, що реалізують складну алгоритмічну логіку, потрібні засоби управління ходом роботи програми: зміни порядку виконання операторів в залежності від різних умов, і ефективної організації роботи часто повторюваних фрагментів. Математично доведено, що будь-який алгоритм можна закодувати за допомогою
- оператора присвоювання
- умовного оператора
- оператора циклу
З оператором присвоювання " : = " ми вже знайомилися в уроці Delphi 2 . Він працює в такий спосіб. Змінна, що стоїть в лівій частині оператора, стає рівною тій величині, яка знаходиться праворуч. Типи цих величин повинні збігатися. У виразі, що стоїть праворуч, також може використовуватися змінна, що стоїть зліва. З математичної точки зору це неправильно, але в програмуванні це означає, що з комірки пам'яті береться початкове значення, виробляються обчислення, і результат записується в цю ж комірку пам'яті, затираючи колишнє значення. Приклад: На початку фрагмента змінна A дорівнює 3, а в кінці -25.
var A, B : Integer;
begin
A:=3;
B:=4;
A:=A*A+B*B;
end;
Умовний оператор дозволяє змінити порядок виконання операторів в залежності від виконання деякого умови. Ось як він записується:
if умова then дію else альтернатива ;
Слова if (якщо), then (тоді), else(інакше) - зарезервовані. Дія і else альтернатива - це будь-які оператори Delphi, або кілька операторів, ув'язнених в логічні дужки begin / end , або виклик підпрограми. Якщо умова істинно, то виконується дія , якщо помилково, то виконується альтернатива .
Умова являє собою логічне вираження. У ньому порівнюються значення виразів (в тому числі також і логічних), виклик функцій, які повертають значення типу Boolean , і комбінування цих значень за допомогою логічних операцій:
знак операції |
Назва операції |
Логічні операції можуть комбінуватися за допомогою зв'язок:
Для деяких типів даних є додаткові операції. Наприклад, для множин - оператор in , який перевіряє, чи входить деяке значення в множину. Наприклад: X: = [2, 4, 5, 7, 8, 10]; Вираз 2 in X істиний (має значення true ); Вираз 6 in X хибний (має значення false ); |
= | дорівнює | |
<> | не дорівнює | |
> | більше | |
< | менше | |
> = | Більше або дорівнює | |
<= | Менше або дорівнює | |
not | Логічне не - заперечення |
Результат виконання операції логічного І дорівнює true , якщо обидва операнда рівні true .
Результат виконання операції логічного АБО дорівнює true , якщо хоча б один з операндів дорівнює true .
Результат виконання операції виключаюче АБО дорівнює true , якщо операнди не рівні один одному.
Оператори циклу дозволяють організувати багаторазове повторення однієї і тієї ж послідовності дій. У Delphi є три оператора, що дозволяють це зробити:
- "Простий" оператор циклу
- умовний оператор циклу
- умовний оператор повторення
Простий оператор циклу застосовується, коли відома кількість повторень циклу. Він записується так:
for лічильник : = вираз-1 to вираз-2
do дію ;
Лічильник - це змінна, яка повинна бути оголошена перед логічним блоком, в якому оператор циклу розташований, і її тип повинен стосуватися одного з перелічуваних типів, зазвичай Integer . вираз-1 і вираз-2 можуть бути як константою або ідентифікатором, так і викликом функції. Дія - один або кілька операторів Delphi . Якщо це група операторів, то вони повинні бути укладені в логічні дужки begin / end . На початку роботи оператора змінна-лічильник отримує значення виразу-1 .Якщо при цьому значення лічильника виявиться менше або дорівнює значенню виразу-2 , то виконуються оператори, що входять в дію . Це і є один цикл. Потім змінна-лічильник приймає значення, що випливає за поточним, і починається новий цикл, тобто порівняння лічильника і вирази-2 , виконання дії , і так далі, до тих пір, поки значення змінної-лічильника не перевищить значення виразу-2 . Можлива робота оператора циклу, при якому змінна-лічильник буде не збільшуватися, а зменшуватися. У цьому випадку ключове слово to замінюється на downto :
for лічильник : = вираз-1 downto вираз-2
do дію ;
Відповідно, вираз-1має бути більше або дорівнює висловом-2 .
Умовний оператор циклу зручно використовувати в тому випадку, коли кількість повторень заздалегідь не відомо:
while умова do
тіло циклу ;
Цей цикл буде виконуватися до тих пір, поки істинно умова (логічний вираз, що повертає значення типу Boolean ). При цьому якщо цей вислів відразу довівнює false , тіло циклу не буде виконано жодного разу. Потрібно дуже уважно стежити за написанням умови і контролем завершення циклу, так як в результаті помилки цикл while буде повторюватися нескінченну кількість разів, що призведе до "зациклення" і " зависання "програми.
Умовний оператор повторення спочатку виконує тіло циклу , а потім вже перевіряє виконання умови
:repeat
тіло циклу
until умова ;
Таким чином, цей варіант циклу гарантує, що тіло циклу буде виконано принаймні один раз. І буде виконуватися до тих пір, поки умова не стане істинною (тобто true ). Варто відзначити, що це єдиний оператор Delphi , в якому тіло циклу не потрібно укладати в логічні дужки begin / end . Початок і кінець тіла циклу визначаються за ключовими словами repeat і until . Разом з операторами циклу використовуються спеціальні команди:
- команда переривання циклу
- команда продовження циклу
Команда переривання циклу застосовується, якщо в процесі виконання операторів тіла циклу з'ясовується необхідність його завершення. Ось ця команда:
Break;
При її виконанні управління передається на перший оператор, наступний за оператором циклу. Команда продовження циклу дозволяє негайно продовжити виконання циклу, пропустивши всі оператори, шо залишилися в тілі циклу, тобто почати наступну ітерацію . Ось ця команда:
Continue;
Справедливості заради варто розповісти про ще один операторі, що дозволяє змінити послідовність виконання програми. Це оператор переходу :
goto мітка ;
В якості мітки може використовуватися будь-який допустимий ідентифікатор або число в діапазоні від 0 до 9999. мітку попередньо необхідно оголосити в розділі опису змінних, але з допомогою не ключового слова var , а ключового слова label :
label міткa ;
або
label список міток ;
Переходити можна як вниз, так і вгору по програмі. Двокрапка відокремлює мітку від оператора, на який відбувається перехід. Приклад використання оператора переходу:
var X, Y: Integer;
label A, B;
begin
A: X:=5 ;
. . .
оператори програми
goto B;
. . .
B: Y:=25;
goto A;
end;
З цього прикладу видно, що оператор end; завершаючий програму, ніколи не буде виконано, тобто програма зациклиться. Саме тому, взагалі, використання оператора переходу є поганим стилем програмування , і без його використання цілком можна обійтися використанням умовних операторів і операторів циклу. Єдиний випадок, коли використання оператора goto може бути виправдано - це вихід з декількох вкладених циклів, що інакше вимагає застосування декількох операторів Break .
Приклад. Сортування одновимірного масиву.
Розглядаються процедури програми, наводяться докладні коментарі. Також можна завантажити проект тут у вигляді архіву. Цикл while і оператори goto використані тільки для демонстрації роботи з ними. Тут - правильніший варіант із застосуванням циклу repeat і оператора break .
Паралельно зауважу, що сортування масиву "методом бульбашки" - неефективний метод. Кількість ітерацій (проходів циклу) росте набагато швидше зростання кількості елементів, пропорційно n2. Сортування 50 000 елементів виконується на комп'ютері секунд за п'ять. Але сортування 100 000 - не за 10 секунд, а близько 35 секунд! Можете поекспериментувати, для цього досить у другому варіанті встановити в описі масиву потрібну кількість елементів.
type Point=Record //Оголошуємом тип: Запис n, digit: Integer; //номер і значення: цілі числа end; var Form1: TForm1; tab: array[1..20] of Point; //Створюємо масив записів типу Point implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.Cells[0, 0]:='Номер';//Ініціалізуємо столбці таблиці StringGrid1.Cells[1, 0]:='Значення'; end; procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin Randomize; //Ініціалізуємо "випадкову" процедуру For i:=1 to StringGrid1.RowCount-1 do begin tab[i].n:=i; //Присвоюємо коміркім масиву порядкові номери tab[i].digit:=Random(100); // Присвоюємо коміркім масиву випадкові значення в діапазоні від 0 до 100 StringGrid1.Cells[0, i]:=IntToStr(i)+'.'; //Номеруемо таблицю StringGrid1.Cells[1, i]:=IntToStr(tab[i].digit); //Переписуємо в таблиюу значення end; end; procedure TForm1.Button3Click(Sender: TObject); begin Application.Terminate; //Процедура завершення програми end; |
|
procedure TForm1.Button2Click(Sender: TObject);
var i, n: Integer; //
Змінна циклу
Sort: Boolean; //Змінна - ознака закінчення сортування
Obmen: Point; //Службова змінна перестановки значень масиву
Label manual1, manual2; //Мітки операторів переходів
begin
Sort:=True; //Ознака невідсортованості масиву
n:=StringGrid1.RowCount-1; //Кількість строчок в таблиці (без заголовка)
if RadioButton1.Checked then goto manual1; //Перехід на ручний режим
while(Sort=True) do //Початок автоматичного режиму: в попередньому циклі була подія сортування
manual1: //Початок ручного режиму
begin
Sort:=False; //Допустимо, что масив вже відсортований (сортування не потрібно)
for i:=1 to n-1 do //Знову проверяємо всі значення від 1 до n
if(tab[i+1].digit < tab[i].digit) then //Провірка на зростання значень. Рівні значення не займаємо
begin //Якщо невірно, то переставляемо сосідні значення:
Obmen:=tab[i]; //1. Зберігаємо одне із значень
tab[i]:=tab[i+1]; //2. На його месце переписсуем сосіднє значенне
tab[i+1]:=Obmen; //3. Переписуєм збережене значенне на нове месце
Sort:=True; //Ознака того, що відбулася подія сортування
end;
if RadioButton1.Checked then goto manual2; //Пропускаємо перехід до нового циклу автоматичного режиму
end; //Тут закінчується поточний цикл авторежиму і здійснюється перехід до нового
manual2:
for i:=1 to n do //Переписуємо відсортовані значення масиву в таблицю
begin
StringGrid1.Cells[0, i]:=IntToStr(tab[i].n)+'.';
StringGrid1.Cells[1, i]:=IntToStr(tab[i].digit);
end;
end;
end.