русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


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


Дата додавання: 2014-11-28; переглядів: 829.


 

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

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 div k краще, чим 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% часу написання, насправді — свідчення не занадто якісної роботи. Добре написаній програмі потрібна не стільки налагодження, скільки тестування на різних припустимих, неприпустимих і "прикордонних" наборах даних. До речі, обмірковування й написання тестів до тестируемого кода сприяє й поліпшенню, і більшої стійкості кінцевого продукту.

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

 

Додаток 7. Рекомендована література

 

Нижче наведені не всі книги по основах програмування на Паскалі, але тільки сучасні й найбільш корисні видання.

 

1. Глинский Я. Turbo Pascal 7.0 і Delphi. Навчальний посібник. / Я. Н. Глинский. — М.: Диасофт, 2001. – 208 с.

2. Гусєва А. Вчимося програмувати: Pascal 7.0. Завдання й методи їх розв'язку. / А. І. Гусєва. М.: Діалог-Мифи, 2005. – 256 с.

3. Зеленяк О. Практикум програмування на Turbo Pascal. Завдання, алгоритми й розв'язку. / О. П. Зеленяк. Спб.: ДиаСофтЮП, ДМК Пресс, 2007. – 320 с.

4. Кетков Ю. Практика програмування: Бейсик, Си, Паскаль. / Ю. Л. Кетков, А. Ю. Кетков. Спб.: БХВ‑ Петербург, 2001. – 480 с.

5. Климова Л. Pascal 7.0. Практичне програмування. Розв'язок типових завдань. / Л. М. Климова. М.: КУДИЦ‑ образ, 2003. – 528 с.

6. Коффман Є. Turbo Pascal. / Є.Б. Коффман. М.: Діалектика, 2002. – 896 с.

7. Культин Н. Програмування в Turbo Pascal 7.0 і Delphi. / Н. Б. Культин. Спб.: БХВ‑ Петербург, 2007. – 400 с.

8. Лукин С.Н. Турбо Паскаль 7.0. Самовчитель для початківців. / С.Н. Лукин. М.: Діалог‑ МИФИ, 2002. – 400 с.

9. Марченко А. Програмування в середовищі Turbo Pascal 7.0. Базовий курс. / А. І. Марченко, Л. А. Марченко. М.: Століття+, 2003. – 464 с.

10. Меженний О. Turbo Pascal. Вчитеся програмувати./ О. А. Меженний М.: Вільямс, 2001. – 448 с.

11. Немнюгин C. Вивчаємо Turbo Pascal. / Л. В. Перколаб, C. А. Немнюгин. СПб: Пітер, 2007. – 320 с.

12. Немнюгин С. Turbo Pascal. / С. А. Немнюгин. Спб.: Пітер, 2006. – 268 с.

13. Фаронов В. Turbo Pascal 7. Початковий курс. / В. В. Фаронов. М.: ОМД Груп, 2003. – 576 с.

14. Фаронов В. Turbo Pascal 7. Практика програмування. / В. В. Фаронов. М.: ОМД Груп, 2003. – 415 с.

15. Федоренко Ю. Алгоритми й програми на Turbo Pascal. Навчальний курс. / Ю. П. Федоренко. СПб: Пітер, 2001. – 240 с.

16. Система програмування Турбо Паскаль: учеб. посібник / Воробйова А. П., Соппа М. С.; Новосиб. гос. архитектур.‑будує. ун‑ т. – Новосибірськ, 2006. – 136 с.

 

 


<== попередня лекція | наступна лекція ==>
Додаток 5. Розширені коди клавіатури | Просто интернет,


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн