Б С Бусигін - Прикладна інформатика - страница 45

Страницы:
1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83 

Рис. 8.73. Порівняння двох символів

31S

Символи можна тільки присвоювати і порівнювати одне з одним. При цьому вони вважаються рівними, якщо рівні їх ASCII-коди. Один символ вважається більше іншого, якщо має більший ASCII-код (рис. S.73).

8.25.2. Опитування клавіатури

Щоб організувати опитування клавіатури нам знадобляться дві процедури. Перши з них "очищує" буфер клавіатури (рис.8.74).

{Файл ClrKey.inc}

Procedure ClrKeyBuf; Var

ch  : Char;

Begin

while KeyPressed do ch:=ReadKey End; {Proc ClrKeyBuf}

Рис. 8.74. Процедура "очищення" буферу клавіатури

У цій процедурі функція KeyPressed повертає логічне значення True, якщо у буфері вводу з клавіатури знаходиться хоча б один символ, і False, якщо буфер пустий.

Коли програма стартує, буфер звичайно пустий. Але будь-яке натискання символьної клавіші (окрім клавіш регістрів Ctrl, Shift, Alt і перемикачів типу NumLock, CapsLock і т.д.) занесе її код у буфер. Коди у буфері будуть зберігатися до тих пір, доки вони не будуть зчитані, або буфер не буде очищений самою програмою.

Функція ReadKey начебто "виймає" послідовно уведені у нього символи по одному за кожне звертання (рос. - обращение). Ця функція завжди повертає один символ, тобто одне значення типу Char. Але у неї є дві важливі особливості:

О символи, які отримані, ніколи не відображаються на дисплеї, тобто ввід символу завжди відбувається "наосліп" (рос. - вслепую);

© режим роботи ReadKey залежить від стану буферу вводу: містить він символи або пуст. Якщо у буфері щось є, то ReadKey поверне перший символ у буфері (той, що був введений раніш за усіх) й видалить цей символ з буферу. Але якщо буфер пустий, то функція ReadKey пристановляє роботу програми й очікує, поки не буде натиснута яка-небудь клавіша, яка генерує символьний

код.

Ці її особливості можна використовувати для побудови декілька корисних конструкцій (змінна ch повинна бути типу Char):

while KeyPressed do

ch:=ReadKey;  {Очистка буферу вводу}

repeat until

KeyPressed;  {Очікування натискання будь-якої клавіші}

Останній цикл завершиться, коли у буфер попаде будь-який символ. Запам'ятайте, що Ваша програма повинна у кінці завжди очищати буфер, інакше усе, що накопичилось у буфері, буде виведено у строку MS-DOS або у редактор середовища програмування.

З урахуванням усього вищенаведеного, представимо другу процедуру, яка очікує натискання клавіші (рис. 8.75).

{Файл Wait.inc}

Procedure Wait; Begin

repeat until KeyPressed End;   {Proc Wait}

Рис. 8.75. Процедура, яка очікує натискання клавіші

Після цього можна визначити програму, яка приймає символ натиснутої клавіші (рис. 8.76).

Program UntilKeyPressed; Uses Crt;

{$I clrkey.inc}  {Підключаємо файл clrkey.inc} {$I wait.inc}      {Підключаємо файл wait.inc}

Var

c : Char;

Begin

ClrScr;

WriteLn('Натисніть будь-яку символьну клавішу'); ClrKeyBuf; {Очищаємо буфер клавіатури}

c:=ReadKey; {Чекаємо натиснення клавіші}

WriteLn('Була натиснута клавіша з символом c);

WriteLn;

WriteLn('Програма тримає паузу до першого

'натискання будь-якої клавіші... ');

Wait; {Чекаємо натиснення клавіші}

ClrKeyBuf {Убираємо "сміття" з буферу}

End.

Рис. 8.7б. Програма, яка приймає символ натиснутої клавіші

8.25.3. Строкові типи (String)

Строковий тип даних визначає множину символьних ланцюжків довільної довжини (від 1 до 255 символів). Його можна уявити себе як масив символів:

CharArray  : Array[1..255]   of Char;

Для визначення строкового типу використовується службове слово String, або це ж слово, поза котрим у квадратних скобках вказується максимальна довжина строки, яка повинна не перевищувати 255:

Type

Line = String; {Строка довжиною 255 символів} Line30 = String[30];  {Строка довжиною 30 символів}

Var

MyLine  : Line; MyLine30   : Line30;

Для описаної строкової змінної довжиною N символів у ТП відводиться N+1 байтів пам'яті, з котрих перший байт за номером "О" містить значення поточної довжини цієї строки, а наступні N байтів призначені для зберігання символів строки, наприклад, 'I know Turbo Pascal' (рис. 8.77). Перевірте цей приклад, маючи на увазі, що код символу "пробіл" дорівнює 32. Будь ласка, перевірте наш приклад за допомогою рис. 8.7б, щоб посвідчитись, що все гаразд.

Номера байтів

0  12 3

4

5

б

7

S

9

10

11

12

13

14

15

17

1S

19

19 73 32 107

110

111

119

32

84

117

114

98

111

32

80

97

115

99

97

108

Вміст байтів

Рис. 8.77. Зберігання символі строки у змінній типу String

При такому способі зберігання у змінній типу String , виникає одна тонкість, яку Ви повинні собі дуже ясно уявляти (рис. S.7S).

Program StrigNumber;

Uses Crt;

Var

St  : String;

Ch : Char; By : Byte;

Рис. 8.78. Перевіримо, що у нульовому байті...

Begin ClrScr;

St:='Let Me Tell You That I Love You Very Much'; WriteLn('Zero Byte Char  : St[0]); WriteLn('Zero Byte Ord: Ord(St[0])); ReadLn End.

Рис. 8.78. Перевіримо, що у нульовому байті... (продовження)

При запуску програми рис.8.78 отримуємо наступний результат (рис. S.79):

 

bo Pascal

 

Zero Zero

 

1

Рис. 8.79. Вміст нульового байту типу String

Ви маєте зробити висновок, що кількість байтів у типі String трактується, як код символу! З цього можна зробити висновок, як треба звертатися до цієї величини. Ще один висновок може бути таким: ТП буде бачити стільки символів строки, яку кількість Ви занесете у нульовий байт.

Таким чином, елементи строки нумеруються цілими числами від 1 до 255. Доступ до кожного елементу строки: S[i]:

MyLine   :=   'ABCD'   {MyLine   : String}

WriteLn  (Ord (MyLine [ 0] ) ) ; {Буде надруковано "4"}

MyLine[0]   := #2;

WriteLn (MyLine) ; {Буде надруковано "AB"}.

Строки можна присвоювати, зливати (конкатенація), порівнювати. А також вводити операціями Read, ReadLn:

Var

Sl,  S2,  S3  : String;

Begin

Sl S2

S3 S3 End.

' Вам ';

' привіт';

Sl + S2;   {S3 =  'Вам привіт'} S3 +  '!';   {S3 =  'Вам привіт!'}

Якщо довжина строки в правій частині перебільшує ліву, то надлишок відтинається.

Порівняння строк виконується за правилами: 1. Більш коротка строка завжди менше ніж більш довга;

2. При рівних довжинах відбувається заелементне порівняння символів цих строк с урахуванням лексикографічної упорядкованості значень стандартного символьного типу Char:

'abcd'

=

'abcd'

■=> True

'abcd'

<> 

'abcde'

■=> True

'abcd'

<> 

'abcd'

■=> True

'abcd'

'abcD'

■=> True

'abcd'

'abc'

■=> True

'aBcd'

'ab'

■=> True

Строки можна вводити з клавіатури. При цьому Ви повинні відслідковувати відповідність введених символів довжині описаних строк

(рис. S.S0).

Program StringInput; Var

Sl  :  String[5];  {Довжина строки Sl - п'ять символів}

Begin

ReadLn(Sl);      {Вводимо б символів: 'Привіт'} WriteLn(Sl);    {Надлишок відтинається. Виводиться: 'Приві' }

ReadLn End.

Рис. 8.80. Відповідність введених символів довжині строки

Для роботи зі строками міститься велика кількість процедур та функцій, які наведені у таблиці 8.50.

Таблиця 8.50.

Процедури та функції

Призначення

Редагування строк

Length(S:  String)   :  Byte     Видає поточну довжину строки

Concat(S1,  S2,   .. . ,Sn ):

String

Повертає конкатенацію тобто злиття строк S1..Sn

Copy  (S:  String; Start, Len:   Integer)   : String

Повертає підстроку довжини Len, яка починається з позиції Start строки S

Delete   (Var S: String; Start,  Len: Integer)

Видаляє з S підстроку довжини Len, яка починається з позиції Start строки S

Insert   (Var S: String; SubS:  String; Start:

Integer)

Вставляє в S підстроку SubS, починаючи з позиції Start

Продовження таблиці 8.50

Pos   (SubS,  S: String;):

Byte

Шукає входження підстроки БиЬБ у строці Б й повертає номер першого символу БиЬБ в Б або 0, якщо Б не містить БиЬБ

Процедури

перетворення

Str   (x[:F[:n]]; Var S:

String)

Перетворює числове значення Х у строкове Б. Можливо задавати формат для Х

Val   (S:  String; Var x; Var ErrCode: Integer)

Перетворює строку Б цифр у значення числової змінної Х

Вправи

1. Які особливі комбінації клавіш існують у комп'ютерах IBM PC?

2. Які корисні функції для роботи з ASCII-символами існують у Турбо Паскалі?

3. За допомогою програми рис. 8.58 виведіть на екран комп'ютера символи, ASCII-коди яких перевищують 240.

4. Створіть на екрані комп'ютера рамки з одинарною та подвійною обвідкою відповідно до рис. 8.61.

5. З використанням програми рис. 8.65 розробіть свою програму, котра опитує клавіатуру й очікує натискання декількох клавіш, відповідно до яких робить конкретні дії.

6. Як розміщується інформація у строкових змінних?

7. Розробіть програму, яка зчитує строкову інформацію з клавіатури та додає її до строкової змінної.

8.26. Рекурсія, множини та текстові файли

8.26.1. Рекурсія

Рекурсія - це традиційна перевага мови Паскаль над іншими мовами програмування. Турбо Паскаль повною мірою дозволяє будувати рекурсивні алгоритми. Під рекурсією розуміється виклик функції (процедури) з тіла цієї ж самої функції (процедури).

Рекурсивність часто використовується в математиці, оскільки багато визначень математичних формул рекурсивні. Як приклад можна привести формулу обчислення факторіала:

У приведених формулах для обчислення кожного наступного значення потрібно знати попереднє. У Турбо Паскалі рекурсія записується так само, як і у формулах:

Function Fact(n  : Word)   : LongInt; Begin

If n=0 Then Fact:=1

Else

Fact  := n*Fact(n -1)

End;

А також - ступеня числа х:

Function IntPower(x  :  Real;  n  : Word)   : Real; Begin

If n=0 Then IntPower:=1

Else

IntPower  :=x*IntPower(x, n-1)

Якщо у функцію передаються n>0, то відбувається наступне: запам'ятовуються відомі значення членів виразу у гілці Else (для факторіала це n, для ступеня - х), а для обчислення невідомих викликаються ті ж функції, але з «попередніми» аргументами. При цьому знову запам'ятовуються (але в

1, якщо n = 0;

n! = і

n!= n *(n -1)!, якщо n > 0.

а також - цілого ступеня числа:

End;іншому місці пам'яті - стеці!) відомі значення членів і відбуваються чергові виклики. Так відбувається доти, поки вираження не стане цілком визначеним (у наших прикладах - це присвоювання гілки Then), після чого алгоритм починає «розкручуватися» у зворотну сторону, вилучаючи з пам'яті «відкладені» обчислені заздалегідь значення. Оскільки при цьому на кожному черговому кроці всі члени виразів вже будуть відомі, через n таких «зворотних» кроків ми одержимо кінцевий результат.

Страницы:
1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83 


Похожие статьи

Б С Бусигін - Прикладна інформатика