Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основи програмування Паскаль.docx
Скачиваний:
51
Добавлен:
12.05.2015
Размер:
511.7 Кб
Скачать

Додаток 5. Розширені коди клавіатури

Натискання клавіші перетвориться у двухбайтовый код, називаний скан‑ ASCII‑ кодом. Цей код міститься в буфер клавіатури, звідки Ваша програма може вважати його за допомогою переривання системи BIOS. Старший байт двухбайтового коду називається скан‑ кодом і є відображенням фактично натиснутої клавіші. Скан‑ код не відбиває стан клавіш Shift, Ctrl або Alt і не є унікальним. Крім скан‑ кодів натискання, існують коди відпускання клавіш, що відрізняються на шестнадцатеричное значення 80 убік збільшення. Молодший байт повного коду, називаний ASCII‑ кодом, також не є унікальним, але повна комбінація скан і ASCII‑ кода унікальна. Деякі клавіші не мають ASCII‑ коду й замість нього вертається нуль. Такі двухбайтовые коди називаються розширеними. При прийманні коду натиснутої клавіші через DOS остання відокремлює від загального значення скан‑ код. Крім того русифікатор, що працює в системі,‑ може додатково транслювати скан коди‑ буквених клавіш в ASCII коди російських букв.

Виходячи зі сказаного, при використанні стандартної функції Readkey, що працює з ASCII‑ кодами клавіш, у загальному випадку є правильної наступна схема обробки на Паскалі:

Ch := Readkey; {Читання символу в байт Ch}

if Ch = #0 then begin

{Якщо немає ASCII‑ коду,

прочитати додатково розширений код}

Ch := Readkey;

{Обробка розширеного коду}

end

else

{Обробка ASCII‑ коду}

На Паскалі десятковий код може бути записаний у вигляді #N, деN– число, наприклад,#65 ('A' латинська). ASCII‑ коди основних друкованих символів можна довідатися з Додатка 1, інші потрібні коди приводяться далі.

Ascii‑ коди

ENTER

13

Пробіл

32

ESC

27

Backspace

8

Tab

9

Розширені коди

Клавіша

Код

Код з Shift

Код з Ctrl

Код з Alt

F1

59

84

94

104

F2

60

85

95

105

F3

61

86

96

106

F4

62

87

97

107

F5

63

88

98

108

F6

64

89

99

109

F7

65

90

100

110

F8

66

91

101

111

F9

67

92

102

112

F10

68

93

103

113

Стрілка нагору

72

Стрілка вниз

80

Стрілка вліво

75

Стрілка вправо

77

Insert

82

Delete

83

Home

71

119

End

79

117

Page Up

73

132

Page Down

81

118

Додаток 6. Правила гарного коду

Написання гарного й ефективного програмного коду — ціле мистецтво, багато в чому, на жаль, подзабытое у зв'язку з вибуховим ростом потужності обчислювальних обладнань, що викликали зниження вимог до якості алгоритмів. Це невеликий додаток не може замінити вивчення спеціалізованих дисциплін, начебто "Технології програмування" або "Теорії алгоритмів і формальних мов", але проходження викладеним тут принципам дозволить починаючому програмістові звикати не просто "вирішувати завдання", а робити це можливо більш гарним і економічним з погляду обчислювальних витрат способом.

1. Структурируйте й вирівнюйте код, принаймні так, як сказано в главі 5. Протягом усієї книги я теж форматував лістинги у звичному для себе стилі. Краще звикнути структурировать текст, зрушуючи будь-які вкладення й розгалуження коду одним‑ двома пробілами вправо. Програма при цьому не "роз'їдеться" далеко вправо на складних блоках, а вид тексту, відкритого в будь-якому редакторі, не буде залежати від розміру відступу табуляції.

2. Давайте змінним осмислені імена. Змінна з іменем Length, або, у крайньому випадку,Dlina, сама нагадає про своє призначення, на відміну відL. C іншої сторони, не забороняється використовувати стандартні скорочення –Sдля площі,Pдля периметра,a,bіc– для сторін трикутника. Будь-які індекси природно виглядають із іменами i,j,kі т.д.  Але якщо індекс позначає, наприклад, номер місяця в році, куди естественней назвати йогоmonth, чомуi. Хоча Паскаль і не розрізняє регістр букв в іменах змінних і службових словах – дотримуйте його скрізь. Більшість професійних мов регістр символів розрізняють.

3. Існує безліч угод про іменах змінних — можна сперечатися про їхні гідності й недоліках, але безперечно одне — дотримання однакового стилю іменування набагато полегшує розуміння й модифікацію програми. У складних проектах осмислених імен змінних може виявитися недостатньо, тоді на допомогу прийдуть префікси. Так, якщо все імена всіх змінн, що ставляться до таблиці "Студенти", починаються наst_, а всі динамічні покажчики мають в імені префіксp_( від англ. "pointer" – покажчик), читати таку програму буде набагато простіше.

4. Створюючи будь-яку змінну, зверніть увагу на наступні моменти:

  • який тип значень може ухвалювати змінна, чи нельзя замінити її перерахуванням, безліччю або іншим "скороченим" типом даних?

  • чи є обмеження на припустимі значення, якщо так, де і як вони будуть враховані?

  • що відбудеться при переповненні значення або спробі дати змінної неприпустиме значення?

5. Закривайте блоки відразу. Такий блок, як

if умова then begin

end

else begin

end;

або

while умова do begin

end;

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

6. Не залишайте непрацюючий додаток "на завтра". Блочно‑ модульна структура програми дозволяє завжди уникнути цього. Підпрограма може бути порожньою "заглушкою", Ви можете використовувати нічого умови, що не роблять, порожні блоки, коментарі, але поточний код повинен компілюватися, якщо завтра Ви не прагнете половину робочого дня затратити на відновлення в пам'яті недоробленого сьогодні.

7. Доводите програму до відсутності попередженькомпілятора, а не тільки помилок. Невідомо, як позначаться насправді ці "безневинні" нагадування. У мові Си конструкція видуif a:=0припустима й викличе лише попередження "Possibly incorrect assignment" — хоча в результаті зміннаaзавждибуде одержувати значення 0 і галузі алгоритму, прив'язана до цієї умови, буде завжди виконуватися.

8. Вибирайте більш короткі типи даних там, де це доречно: часто Byteможе замінитиWordабоInteger, аString[20]— простоString.

9. Застосовуйте можливо більш ефективний алгоритм розв'язку — насамперед, оцінка ефективності пов'язана із залежністю числа виконуваних операцій від розмірності даних. Подвійний цикл повної обробки всіх елементів матриці простий у вивченні, але далеко не завжди є кращим розв'язком при роботі з реальним завданням – адже трудомісткість цього алгоритму рівна n2, де n — розмірність матриці.

10. Вибирайте менш трудомісткі операції. Так, n divkкраще, чимTrunc(n/k), аInc(i);краще, чимi:=i+1;. У всіх випадках порядкові оператори й операнды працюють швидше, чим дійсні. Тому обходитеся порядковими даними скрізь, де це можливо. Особливо уникайте без необхідності розподілу на дійсні числа.

11. Не забувайте про погрішності при роботі з речовинними числами. Хрестоматійне while x<=2.5 do …— погано, якщоx— речовинний. З іншого боку,while abs(x-2.5)<epsвиглядає громіздко й вимагає зайвих обчислень. Найкращеwhile x<=2.5+eps, оптимизирующий компілятор однаково перетворить2.5+epsу константу.

12. Використовуйте стандартні функції мови, на якій пишете. Уявна економія ресурсів, досягнута написанням власних підпрограм нижнього рівня, обернеться трудноуловимыми помилками в більших проектах. Після п'яти‑ десяти років практики це стає ясно кожному програмістові, хоча експерименти із власними інтерфейсами й машинно‑ орієнтованими програмами бувають цікаві й навіть корисні на етапі навчання.

13. Стежите за умовами. Якщо Ви перевіряєте те саме умова кількаразова — скоріше всього, у Вашої програми не в порядку з логікою. Приклад з розділу 7.7 показує це наочно.

14. Не забувайте про взаємовиключні умови. Складений умовний оператор if … else ifабо жcaseу таких випадках набагато краще набору коротких умовних операторів.

15. Найчастіше при написанні довгих фрагментів коду зручніше обробляти помилки у вигляді

if помилка then завершення;

обробка;

чим за схемою

if вірно then обробка

else завершення;

Взагалі, уникайте elseрядків, що перебувають, через 100послусвого if — це утрудняє сприйняття навіть гарне структурованої програми.

16. Уникайте в циклах обчислень, що не залежать від їхніх параметрів! Вирази начебто Sin(Pi/n), поміщене в цикл, деnне міняється, виглядає безглуздо. Адже кожне обчислення синуса ( як і інших стандартних функцій) — це трудомістке розкладання в ряд Фур'є, виконуване машиною.

17. Використовуйте математику там, де це доречно для скорочення трудомісткості коду й числа порівнянь. Перевірити, що змінні xіyмають один знак, можна так:

if (x>0) and (y>0) or (x<0) and (y<0) then …,

а можна й у вигляді

if (x*y>0) then …

18. Припиняйте цикли, коли результат уже досягнуться. Пріоритет засобів при цьому наступний:

  • використання циклів repeat-untilабоwhile-doзамістьfor;

  • оператори breakабоexit;

  • в останню чергу – goto, і тільки у випадках, описаних у розділі 16.2.

19. Тимчасовий "робітник" масив того ж порядку, що створюваний або прочитаний з файлу — майже завжди не кращий розв'язок. Його використання говорить про те, що завдання вирішується "у чоло" і не кращим способом. Припустимим уважається використання одномірного робочого масиву при обробці матричних даних — якщо розмірність його не перевищує більшої з размерностей матриці.

20. Іменуйте розмірні константи масивів! Нікому не потрібні кілька циклів з верхніми границями-"близнюками". А що, якщо розмірність оброблюваних даних прийде змінити?

21. Передавайте значення підпрограмам переважно за адресою, а не за значенням. Для матричних і векторних даних намагайтеся робити це завжди. Застосування векторних даних має пріоритет перед матричними.

22. Не робіть підпрограми залежними від глобальних даних. Недотримання цього правила суттєво зменшити ймовірність повторного використання коду Вами або іншим розроблювачем.

23. Не пишіть підпрограм, що повертають більш одного об'єкта — скаляра, вектора або матриці. У крайньому випадку, можна окремим параметром передавати або повертати розмірність векторних даних. Уникайте підпрограм, які нічого не повертають. Розробка складних підпрограм полегшує, якщо їх "крапка виходу", що й вертається значення зазначені єдиним і останнім оператором. Для переходу з тіла підпрограми в крапку повернення в цьому випадку не грішно використовувати навіть goto:

function Test (a,b:integer):integer;

label End_of_Test;

var error:integer;

begin

error:=0;

if (a<0) or (b<0) then begin

error:=1;

goto End_of_Test;

end;

. . .

End_of_Test:

Test:=error;

end;

24. Потрібно привчити себе не тільки правильно називати змінні й функції, але й виділяти всі логічні частини завдання при проектуванні ієрархії підпрограм. Наприклад, якщо функція шукає в наборі даних елемент за якоюсь ознакою, і створює новий у тому випадку, коли шуканий елемент виявлений, то краще розділити її на дві — функцію пошуку й функцію створення нового вузла, яка буде викликатися з першої. Досить дотримуватися подібних немудрих прийомів, щоб підвищити сопровождаемость програми в рази. Якщо подивитися на запитання з іншого боку, не змушуйте одну підпрограму виконувати кілька функцій — вона виявиться пошук з погляду повторного використання коду. Так, визначення довжини ламаної лінії можна реалізувати однієї підпрограмою, але набагато краще, якщо завдання розбите на підпрограми обчислення довжини й обчислення відстані між двома крапками.

25. При роботі з динамічними об'єктами пишіть код так, щоб відкриті об'єкти завжди закривалися, як тільки вони стануть не потрібні. В ідеалі порядок закриття об'єктів повинен бути зворотним стосовно порядку відкриття (останній об'єкт, що зайняв пам'ять, звільняє її першим). Слід також уникати функцій перерозподілу раніше виділеної динамічної пам'яті.

26. Перевірити логікові своєї програми легше всього за принципом "Одне виправлення — одне місце в програмі". Якщо при додаванні в меню нового пункту або, ще гірше, простій зміні розмірності одномірного масиву доводиться переписувати трохи вилучених друг від друга фрагментів коду – програма написана погано.

27. Якщо написана Вами програма не працює або працює "криво", помилка лежить на вашій совісті, а комп'ютер з компілятором ні в чому не винуваті. "Налагодження", при якій програміст хаотично міняє те одне, те інше місце в коді й на яку йде до 90% часу написання, насправді — свідчення не занадто якісної роботи. Добре написаній програмі потрібна не стільки налагодження, скільки тестування на різних припустимих, неприпустимих і "прикордонних" наборах даних. До речі, обмірковування й написання тестів дотестируемого кода сприяє й поліпшенню, і більшої стійкості кінцевого продукту.

Резюмуючи, можна сказати, що все більші програми на світі написані тільки за рахунок одного — правильного структурування коду. І гарний програміст — не той, хто "знає мови", а той, хто вміє писати, що легко читається, розуміється код, що й модифікується, максимально використовуючи стандартні засоби мови розробки.