Інструкція case

У попередньому прикладі, в програмі контролю ваги, множинний вибір був реалізований за допомогою вкладених одна в іншу інструкцій if. Такий підхід не завжди зручний, особливо в тому випадку, якщо кількість варіантів ходу програми велике.

У мові Delphi є інструкція case, яка дозволяє ефективно реалізувати множинний вибір. У загальному вигляді вона записується в такий спосіб:

case Селектор of спісок1:

begin
{Інструкції 1} end; спісок2:

begin
{Інструкції 2} end; спісокМ:

begin
{Інструкції N}

end;

else
begin
{Інструкції)

end;

end;

де:

  • Селектор – вираз, значення якого визначає подальший хід виконання програми (т. е. послідовність інструкцій, яка буде виконана);
  • Список N – список констант. Якщо константи представляють собою діапазон чисел, то замість списку можна вказати першу і останню константу діапазону, розділивши їх двома точками. наприклад, список 1, 2, 3, 4, 5, 6 може бути замінений діапазоном 1..6.

Виконується інструкція case наступним чином:

  1. спочатку обчислюється значення виразу-селектора.
  2. Значення виразу-селектора послідовно порівнюється з константами зі списків констант.
  3. Якщо значення виразу збігається з константою зі списку, то виконується відповідна цьому списку група інструкцій. На цьому виконання інструкції САSЕ завершується.
  4. Якщо значення виразу-селектора не збігається з жодною константою з усіх списків, то виконується послідовність інструкцій, наступна за else.

Синтаксис інструкції case дозволяє не писати else і відповідну послідовність інструкцій. В цьому випадку, якщо значення виразу не збігається з жодною константою з всіх списків, то виконується наступна за case інструкція програми.
На рис. 2.7 наведено алгоритм, реалізований інструкцією case.

Рис. 2.7. Алгоритм, реалізований інструкцією case Нижче наведені приклади інструкції case.

case n_day of
1,2,3,4,5: day: = 'Робочий день. ';
6: day: = 'Cyббoтa!';
7: day: = 'Воскресіння!';
end;
 case n_day of 1..5: day: = 'Робочий день.';
 6: day: = 'субота!';
 7: day: = 'Воскресіння!';
 end; case n_day of 6: day: = 'субота!';
 7: day: = 'Воскресіння!'; 
else day: = 'Робочий день.';
 end;

Як приклад використання інструкції case розглянемо програму, яка перераховує вагу з фунтів в кілограми. Програма враховує, що в різних країнах фунт  “важить” по різному. Наприклад, в Росії фунт дорівнює 409,5 грамів, в Англії – 453,592 грами, а в Німеччині, Данії та Ісландії фунт важить 500 грамів.
У діалоговому вікні програми, зображеному на рис. 2.8, для вибору країни використовується список Країна.


Рис. 2.8. Діалогове вікно програми Приклад використання case

Для вибору назви країни використовується список – компонент ListBox. Значок компонента ListBox знаходиться на вкладці Standard (рис. 2.9). Додається список до форми додатка точно так же, як і інші компоненти, наприклад, командна кнопка або поле редагування. У табл. 2.5 наведені властивості компонента ListBox.


Рис. 2.9. Компонент ListBox

Табліца2.5. Властивості компонента ListBox

Властивість Визначає
Name Ім’я компонента. В програмі використовується для доступу до властивостей компонента
Items Елементи списку
Itemindex Номер вибраного елемента списку. Номер першого елемента списку дорівнює нулю
Left Відстань від лівої межі списку до лівої межі форми
Top Відстань від верхньої кордони списку до верхньої межі форми
Height Висоту поля списку
Width Ширину поля списку
Font Шрифт, використовуваний для відображення елементів списку
Parent-Font Ознака успадкування властивостей шрифту батьківської форми

Найбільший інтерес представляють властивості Items і Itemindex. Властивість items містить елементи списку.
Властивість itemindex задає номер обраного елемента списку. Якщо жоден з елементів не обраний, то значення властивості рівне мінус одиниці.
Список може бути сформований під час створення форми або під час роботи програми.
Для формування списку під час створення форми треба у вікні Object Inspector вибрати властивість items і клацнути на кнопці запуску редактора списку рядків (рис. 2.10).


Рис. 2.10. Кнопка запуску редактора списку

У діалоговому вікні String List Editor (рис. 2.11) потрібно ввести список, набираючи кожного елемент списку в окремому рядку. Після введення чергового елемента списку для переходу до нового рядка необхідно натиснути клавішу & lt; Enter & gt ;. після введення останнього елемента клавішу ” Enter “натискати не треба. Завершивши введення списку, слід клацнути на кнопці ОК.


Рис. 2.11. Редактор списку

У табл. 2.6 перераховані компоненти форми додатка, а в табл. 2.7 наведені значення властивостей компонентів.

Таблиця 2.6. Компоненти форми

Компонент Призначення
ListBoxl Для вибору країни, для якої треба виконати перерахунок
Editl Для введення ваги у фунтах
Label1, Label2, Label3 Для виведення пояснювального тексту про призначення полів введення
Label4 Для виведення результату перерахунку
Button1 Для активізації процедури перерахунку ваги з фунтів в кілограми

 

Таблиця 2.7. Значення властивостей компонентів

Властивість Значення
Form1 .Caption Приклад використання case
Editl. Text
Label1. Caption Виберіть країну, введіть кількість фунтів і клацніть на кнопці Обчислити
Label2 .Caption Країна
Label3. Caption Фунтів
Button1. Caption Обчислити

Процедура перерахунку, яка виконується в результаті клацання на командній кнопці Обчислити, примножує вага в фунтах на коефіцієнт, що дорівнює кількості кілограмів в одному фунті. значення коефіцієнта визначається за номером обраного зі списку елемента.
У лістингу 2.3 приведений текст програми перерахунку ваги з фунтів в кілограми.
Лістинг 2.3. Перерахунок ваги з фунтів в кілограми

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = Class (TForm)
Label2: TLabel;
Editl: TEdit; // поле введення ваги у фунтах
Button1: TButton; // кнопка Обчислити
Label1: TLabel;
LabelS: TLabel;
ListBox1: TListBox; // список країн
Label4: TLabel; // поле виведення рез-та - ваги в кілограмах
procedure FqrmCreate (Sender: TObject);
procedure ButtonlClick (Sender: TObject); private
{ Private declarations} public
{Public declarations} end;
var
Form1: TForml;
implementation
{$ R * .DFM}
procedure TForml.FormCreate (Sender: TObject);

begin
{
ListBox1.items.add ( 'Росія');
ListBox1.items.add ( 'Австрія');
ListBox1.iterns.add ( 'Англія');
ListBox1.items.add ( 'Німеччина');
ListBox1.iterns.add ( 'Данія');
ListBoxl.iterns.add ( 'Ісландія');
ListBox1.iterns.add ( 'Італія');
ListBox1.items.add ( 'Нідерланди'); }
ListBox1.itemindex: = 0; end;
procedure TForm1.ButtonlClick (Sender: TObject);

var
funt: real; // вагу в фунтах

kg: real; // вагу в кілограмах

k: real; // коефіцієнт перерахунку

begin
case ListBoxl.Itemindex of

0: k: = 0.4095; // Росія

1: k: = 0.453592; // Англія

2: k: = 0.56001; // Австрія
3..5,7: k: = 0.5; // Німеччина, Данія, Ісландія, Нідерланди

6: k: = 0.31762; // Італія

end;
funt: = StrToFloat (Editl.Text);

kg: = k * funt;

label4.caption: = Editl.Text
+ 'Ф. - це '
+ FloatToStrF (kg, ffFixed, 6,3) + 'кг.';

end;
end.

Слід звернути увагу на процедуру обробки події FormCreate, яке відбувається в момент створення форми (форма створюється автоматично при запуску програми). Цю процедуру можна використовувати для ініціалізації змінних програми, в тому числі і для додавання елементів в список. У наведеному тексті програми інструкції створення списку закоментовані, т. к. список був створений за допомогою редактора рядків під час створення форми.
Розглянемо ще один приклад використання інструкції case. При виведенні числової інформації з поясняющим текстом виникає проблема узгодження виведеного значення і закінчення поясняющего тексту.
Наприклад, в залежності від числового значення пояснювальний текст до грошової величиною може бути: “рубль”, “ рублів“ або “рубля “ (123 рубля, 120 рублів, 121 рубль). Очевидно, що закінчення поясняющего слова визначається останньою цифрою числа, що відображено в табл. 2.8.

Таблиця 2.8. Залежність закінчення тексту від останньої цифри числа

Цифра                     Пояснювальний текст
0, 5, 6, 7, 8, 9 рублів
1 Рубль
2,3,4 Рубля

 

Наведене в таблиці правило має виняток для чисел, що закінчуються на 11, 12, 13, 14. Для них пояснювальний текст повинен бути  “рублів”.
Діалогове вікно програми наведено на рис. 2.12, а текст – в лістингу 2.4. Пояснювальний текст формує процедура обробки події onKeyPress.

Рис. 2.12. Діалогове вікно програми

Лістинг 2.4. формування поясняющего тексту

unit. rub_l; interface
uses
Windows, Messages, SysUtils,

Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = Class (TForm) Label1: TLabel;

Editl: TEdit; Label2: TLabel;

procedure EditlKeyPress (Sender: TObject; var Key: Char);
private
{Private declarations} public
{Public declarations} end;
var
Form1: TForm1;
implementation
{$ R * .dfm}
// натискання клавіші
procedure TForm1.Edit1KeyPress (Sender: TObject; var Key: Char) var
n : Integer; // число
r : Integer; // залишок від ділення n на 10

text: string [10]; // формується пояснювальний текст

begin
if Key = chr (VK_RETURN) then

begin
n : = StrToInt (Editl.Text); if n & gt; 100
then n: = n mod 100;

if (N & gt; = 11) and (n & lt; = 14) then
text: = ' рублів ' else begin
r: = n mod 10; case r of
1: text: = 'рубль'; 2 .. 4: text: = 'рубля';

else text: = 'рублів';

end;

end;
Label2.Caption : = IntToStr (n) + text; end;
end;

end.

Розглянемо фрагмент програми (лістинг 2.5), яка обчислює дату наступного дня, використовуючи сьогоднішню дату, представлену трьома змінними: day (день), month (місяць) і year (рік).
Спочатку за допомогою інструкції сазе перевіряється, чи є поточний день останнім днем ​​місяця. якщо поточний місяць – лютий і якщо поточне число – 28, то додатково виконується перевірка, чи є рік високосним. Для цього обчислюється залишок від ділення року на 4. Якщо залишок дорівнює нулю, то рік високосний, і число 28 не є останнім днем місяця.
Якщо з’ясовується, що поточний день – останній день місяця, то наступне число – перше. Потім перевіряється, чи не є поточний місяць груднем. Якщо немає, то збільшується номер місяця, а якщо так, то збільшується номер року, а номером місяці присвоюється значення 1.

Лістинг 2.5. Обчислення дати наступного дня (фрагмент)

// обчислення дати наступного дня

var
day: integer; // день
month: integer; // місяць
year: integer; // рік
last: boolean; // якщо день - останній день місяця,
// то last = True
r: integer; // якщо рік не високосний, то залишок

// від ділення year на 4 не дорівнює нулю
begin
{Змінні day, month і year містять сьогоднішню дату}
last : = False; // нехай день - не останній день місяця

case month of 4,6,9,11:

if day = 30 then last: = True; 2:

if day = 28 then begin
r: = year mod 4; if r & lt; & gt; 0 then last: = True;

end;
else: if day = 31 then last: = True;

end; if last then
begin // останній день місяця day: = 1;

if month = 12 then
begin // останній місяць

month: = 1;

year: = year + 1;

end
else month: = month + 1;

end

else day: = day + 1;
// змінні day, month і year // містять завтрашню дату

end;