Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Завдання цього параграфа – розробити програму електронного годинника. На прикладі цієї програми ви вивчите роботу процедур опитування часу та методи побудови рухомих зображень.
Для опитування внутрішнього годинника, який є в кожному комп’ютері, використовують процедуру Time(h,m,s), яка надає змінним h, m та s значення години, хвилини та секунди на момент звертання до неї. Досить поставити таке опитування в циклі, щоразу виводити значення часу і годинник готовий.
Program Clock1;
Var h,m,s:integer;
Begin
While not IsEvent do
Begin
Time(h, m, s);
WriteLn(h, m, s);
End;
End.
Якщо запустити таку програму, то відразу видно всі її недоліки. По-перше, кожне нове значення часу виводиться у новому рядку. По-друге, протягом однієї секунди програма декілька разів виводить одне й те саме значення. Так і повинно бути, бо протягом секунди тіло циклу може виконуватись десятки разів.
Щоб позбутися цього, будемо виводити значення часу тільки тоді, коли покази годинника мають змінитися. Для цього введемо нову змінну sold, значенням якої буде число секунд, яке вже виведене. Наступне виведення здійснюватимемо лише тоді, коли отриманий час відрізняється від вже виведеного. А перед оператором виведення часу поставимо оператор встановлення позиції виведення, щоб нове значення часу виводилося на тому ж місці, затираючи старе зображення.
Для повноти інформації виведемо ще й дату. Для визначення дати використовують процедуру Дата:
Date (var Рік,Місяць,День:integer).
Процедура Дата присвоює фактичним параметрам, які повинні бути цілими змінними, значення показників системної дати у момент звертання. Ця процедура використовує три змінні. Але звертання до неї відбувається лише раз, тому ми можемо скористатися тими ж змінними, що й для визначення часу, хоч їхніми значеннями будуть рік, місяць та день календарної дати. Виведемо інформацію в зручнішій формі і програма може вважатися найпростішим цифровим електронним годинником.
Program Clock2;
var h,m,s,sold:integer;
Begin
Date(h,m,s);
Write(h,':',m,':',s);
sold:=0;
While not isevent do
Begin
Time(h,m,s);
If s<>sold then
Begin
Moveto(0,40);
Write(h:2,' год ',m:2,' хв ',s:2,' сек');
sold:=s
End
End;
End.
Практичне завдання
1. Недоліком наведеної програми є те, що виведена дата опівночі не зміниться. Вдоскональте програму, щоб виправити це.
2. Додайте до даної програми графічне зображення календаря, на якому буде виводитись дата, та зображення електронного годинника для виведення часу.
4.2. Інтерпретатор простих виразів
Теорія конструювання мов програмування та перекладу програм з однієї мови на іншу, зокрема машинну, є окремою галуззю науки. У цьому параграфі ви ознайомитесь з елементами процесу розпізнавання і виконання програм на прикладі простого інтерпретатора числових арифметичних виразів.
Розглянемо таку задачу. З клавіатури вводять рядок тексту, який містить цілі числа, розділені знаками арифметичних операцій. Треба обчислити і вивести значення виразу. Для спрощення вважаємо, що рядок не містить пропусків і починається з числа.
Аналіз тексту, який потрібно інтерпретувати (у нашому випадку арифметичного виразу, значення якого треба обчислити), побудуємо таким чином, щоб текст вводився символ за символом і відразу аналізувався. Це дає змогу не тримати в оперативній пам'яті всього тексту.
Відомі з арифметики поняття множник, ділене, дільник об’єднаємо збірним поняттям множник. Аналогічно, поняття зменшуване, від'ємник, доданок об'єднаємо поняттям доданок. Отже, вираз складається з доданків а доданки з множників. Будемо розробляти програму так, щоб доданку і множнику відповідали функції, які вводять всі символи даного елементу виразу і обчислюють значення цього елементу. Опишемо змінну Character, яка міститиме поточний прочитаний символ.
Розглянемо процес введення числа. Число вводиться цифра за цифрою і введення завершується, коли черговий введений символ не є цифрою. Але ж ми вже ввели його! Вияснити, яким буде наступний символ не прочитавши його неможливо. Тому мусимо сформулювати таке правило: процедура чи функція, яка аналізує елемент виразу (доданок або множник), вводить також наступний символ, який вже не належить до даного елементу. Наслідком цього правила є той факт, що перший символ кожного елементу виразу вводиться до виклику функції, яка аналізує цей елемент. На малюнку наведений приклад, який ілюструє це правило.
Товстою лінією підкреслене число 1458, яке вводиться. Символ “1” був введений при попередньому виклику процедури і є значенням змінної Character. Функція, яка аналізує число, вводить виділені символи, а після її завершення змінна Character набуває значення “–“.
Опишемо необхідні змінні:
Program Expression;
Var
Character:char;
Value:real;
Напишемо функцію Factor для введення та обчислення множника. При цьому використаємо той факт, що в таблиці кодування символів цифри упорядковані і мають номери від 48 ("0") до 57 ("9"). Множники в нашому випадку є цілими числами. Функція Factor вводить множник цифра за цифрою, поки не зустрінеться символ, який не є цифрою. Наведемо текст цієї функції:
Function Factor:integer;
Var Number:integer;
Begin
Read(Character);
Number:=0;
Repeat
Number:=Number*10+ord(Character)- Ord('0');
Read(Character);
until (Character<'0') or (Character>'9');
Factor:=Number
end;
Напишемо також функцію Item для обчислення доданка. Функція Item вводить числа (множники), поки вони сполучені знаками множення та ділення і виконує відповідні операції:
Function Item:real;
Var Number:real;
Begin
Number:=Factor;
While (Character='*') or (Character='/') do
If Character='*' then
Number:=Number*Factor
else
Number:=Number/Factor;
Item:=Number;
End;
Тепер залишилось вводити доданки, поки вони сполучені символами додавання або віднімання, і виконувати дії. Зробимо це у виконуваній частині головної програми.
Begin
Value:=Item;
While (Character='+') or (Character='-') do
If Character='+' then
Value:=Value+Item
else
Value:=Value-Item;
Write(Value)
End.
Проаналізуємо ще раз роботу всієї програми. У головній програмі вводиться перший символ і викликається функція Item. Функція Item звертається до функції Factor, яка повертає перше число. Якщо далі записано символ множення або ділення, то функція Item читає наступний символ і знову звертається до обчислення множника. Коли ж зустрінеться будь-який символ крім цифри, "*" і "/", то обчислення доданка припиняється і його значення повертається в головну програму. Головна програма аналогічно формує значення виразу за допомогою операцій додавання та віднімання. Легко бачити, що виконання програми завершується, коли зустрінеться символ кінця рядка або інший непередбачений символ. Перевірте це!
Практичне завдання
1) Змініть функцію Factor так, щоб буква "р" сприймалась програмою, як число 3.14.
2) Опишіть процес обчислення виразу у вигляді окремої функції Expr, щоб виконувана частина головної програми могла бути записана в такому вигляді:
Begin
Write(Expr)
End.
4.3. Проектуємо калькулятор
Працюючи на комп'ютері, ми настільки звикли до різноманітних кнопок і кнопочок на екрані монітора, що використовуємо їх так само легко, як кнопки справжньої клавіатури. При цьому не завжди задумуємось, що вся картина на екрані – це результат роботи програмного забезпечення. Здається, що створити все це надзвичайно складно і така робота вимагає сучасних середовищ візуального програмування. Розглянемо на прикладі розробки програми-калькулятора способи побудови та використання кнопок.
Зображати та використовувати кнопки на екрані монітора просто і легко. Щоб переконатись в цьому розгляньте уважно малюнок. Якщо верхню і праву сторони прямокутника, намальованого на однотонному тлі, виділити світлішим кольором, а нижню і ліву – темнішим, то створюється враження, що це – кнопка, яка виступає над пов ерхнею планки. Поміняємо кольори місцями – кнопка виявиться «натиснутою». При цьому, щоб змінити вигляд кнопки, довить перемальовувати лише межі прямокутника, а його заповнення залишати незмінним. Очевидно, що так легко зображати можна лише прямокутні кнопки.
Розробимо програму, яка реалізує простий калькулятор для роботи з цілими числами та демонструє використання програмно створених (віртуальних) кнопок.
Щоб почати роботу, програміст має чітко уявляти собі вигляд екрану під час роботи програми. Нехай майбутній калькулятор виглядатиме приблизно так, як показано на малюнку.
Корпус калькулятора, екран, кнопки будемо малювати процедурами, для яких вхідними параметрами будуть координати лівого верхнього кута (left,top), ширина (width) та висота (height) відповідного прямокутного елементу.
Опишемо необхідні змінні:
program Calc;
const but_size=50;{--Розмір кнопки--}
but_sym='789+456-123*0C=/';
{-написи на кнопках згідно розташування--}
var i,j,t:integer;
now_number,save_number,num_add:integer;
k,x,y:integer;
operator:char; is_error:boolean;
Процедура для малювання корпуса калькулятора:
procedure draw_corpus(left,top,width,height:integer);
Begin
pen(1,0,0,0);
brush(1,100,120,120);
rectangle(left,top,left+width,top+height);
pen(3,0,0,0);
line(left,top,left,top+height);
line(left,top+height,left+width,top+height);
pen(3,150,170,170);
line(left,top,left+width,top);
line(left+width,top,left+width,top+height);
end;
Процедура для малювання екрану калькулятора draw_screen містить додатковий параметр для введення числа (number) і перевірки коректності введення даних (err).
procedure draw_screen (left,top,width, height, number:integer; err:boolean);
Begin
pen(1,0,0,0);
brush(1,150,170,170);
rectangle(left,top,left+width,top+height);
pen(2,200,200,200);
line(left,top,left,top+height);
line(left,top+height,left+width,top+height);
pen(2,0,0,0);
line(left,top,left+width,top);
line(left+width,top,left+width,top+height);
font(18,0,700);
if (err=true) then
Begin
moveto(left+12,top+2);
write(' E R R O R')
End
else
Begin
moveto(left+12,top+2);
write(abs(number):12);
{якщо число від’ємне, то вивести ‘-‘}
if (number<0) then
Begin
moveto(left+12,top+2);
write('-')
End
End
End;
Процедура для малювання кнопки:
procedure draw_button (left,top,width,height:integer; capt:string; is_pushed:boolean);
var sx,sy:integer;
Begin
pen(1,0,0,0);
Brush(1,200,200,200);
rectangle(left,top,left+width,top+height);
{--якщо кнопка натиснута--}
if (is_pushed=true) then
Begin
pen(2,250,250,250);
line(left,top,left,top+height);
line(left,top+height,left+width,top+height);
pen(2,0,0,0);
line(left,top,left+width,top);
line(left+width,top,left+width,top+height);
sx:=7; sy:=13
End
else
Begin
pen(2,0,0,0);
line(left,top,left,top+height);
line(left,top+height,left+width,top+height);
pen(2,250,250,250);
line(left,top,left+width,top);
line(left+width,top,left+width,top+height);
sx:=10; sy:=10
End;
font(15,0,700);
moveto(left+5+sx,top+sy);
write(capt)
end;
Наступна функція забезпечує процес введення інформації від користувача до калькулятора. Вона реалізує очікування натискання кнопки миші і повертає номер кнопки, яку натиснув користувач. Очевидно, що така функція повинна повертати ціле значення. Найскладнішим елементом цієї функції є визначення номера t кнопки, якій належить точка з координатами (х,y), в якій була натиснута кнопка миші. Для цього ми використаємо стандартну функцію event(k,x,y), яка аналізує натиснення лівої кнопки миші (k=2) та дозволяє визначити значення x та y.
function get_event:integer;
var i,j,t:integer;
Begin
get_event:=-1;
event(k,x,y);
if k=2 then
Begin
t:=1;
for i:=1 to 4 do
for j:=1 to 4 do
Begin
if ((x>j*65+10)and(x<j*65+10+but_size)) and
((y>i*65+100)and(y<i*65+100+but_size)) then
Begin
get_event:=t;
{---імітуємо зображення натиснення кнопки--} draw_button(j*65+10,i*65+100,but_size,but_size,but_sym[t],true);
delay(150);
End;
t:=t+1;
End;
End;
End;
Головна програма матиме такий вигляд:
Begin
clear; write('Press Esc to Exit.');
now_number:=0; save_number:=0; k:=0; operator:='n'; is_error:=false;
draw_corpus(50,50,300,400);
while not((k=1)and(x=27)) do
Begin
is_error:=false;
if (now_number>99999999) then
begin now_number:=0;
save_number:=0;
is_error:=true;
end;
draw_screen(70,80,260,40,now_number,is_error);
t:=1;
for i:=1 to 4 do
for j:=1 to 4 do
Begin
draw_button(j*65+10,i*65+100,
but_size,but_size,but_sym[t],false);
t:=t+1;
End;
j:=get_event; num_add:=-1;
case j of
1: num_add:=7;
2: num_add:=8;
3: num_add:=9;
4: begin save_number:=now_number; now_number:=0; operator:='+'; end;
5: num_add:=4;
6: num_add:=5;
7: num_add:=6;
8: begin save_number:=now_number; now_number:=0; operator:='-'; end;
9: num_add:=1;
10: num_add:=2;
11: num_add:=3;
12: begin save_number:=now_number; now_number:=0; operator:='*'; end;
13: num_add:=0;
14: begin now_number:=0; save_number:=0; operator:='n'; end;
16: begin save_number:=now_number; now_number:=0; operator:='/'; end;
15: begin
case (operator) of
'+': begin now_number:=save_number +now_number; save_number:=0; operator:='n'; end;
'-': begin now_number:=save_number-now_number; save_number:=0; operator:='n'; end;
'*': begin now_number:=save_number *now_number; save_number:=0; operator:='n'; end;
'/': begin now_number:=save_number div now_number; save_number:=0; operator:='n'; end;
End;
End;
End;
if (num_add<>-1) and (now_number<=99999999)
then now_number:=now_number*10+num_add;
End;
End.
Дата публикования: 2014-11-04; Прочитано: 732 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!