18 май 2017 г.

My Bad Code #1 - Как да НЕ пишете код (една от първите ми програми)

Е, отдавна не бях писал на тема програмиране, но нека бързо променим това! Не, не съм се отказал и не, не съм загубил интерес - просто приоритетите ми малко се измениха. 😉

Хрумна ми идеята да ви покажа част от кода, който аз самият съм писал... и да ви покажа най-лошите си грешки, с цел да ги избегнете когато се учите да програмирате.

В тази поредица ще ви покажа ПРОВАЛИТЕ си, за да видите, че всъщност програмирането НЕ е нещо, което научаваш веднъж като да караш колело и след това вече всичко си стои на мястото завинаги.

Истината е, че в началото няма да знаеш какво правиш и ще правиш някои доста нелепи грешки, без дори да ги осъзнаваш. В това няма проблем, но е хубаво да се учиш от грешките си и постепенно да изглаждаш нещата където е необходимо.



В този пост ще ви покажа една от първите програми, които НЯКОГА съм писал.

Be gentle. 👀


---



Истинска красота, нали? 😀

Нека анализираме постъпково колко ужасен е този код всъщност!


Какъв е проблемът тук? Първо, че съм използвал имменото пространство std. Написах цял пост за това защо това в повечето случаи не е добра практика. 

Следващият проблем идва от факта, че просто импортирам много библиотеки, които не ползвам в тази програма или пък дори и да ги ползвам... няма нужда да ги ползвам. Къде например влиза в употреба библиотеката math.h? Отговорът е никъде.

Всъщност причината да включа тези редове в програмата си е доста забавна - просто мислех, че са абсолютно необходими, за да може кодът да се компилира успешно! Това е добър урок да проучвате всеки един ред, който пишете, а не да минавате с оправданието "еми така го пишеше в учебника".


Тук вече става мазало! 😅

Първо - void main()? Не, само не и void main()! Не знам защо постоянно ни даваха примери, в които main() е void функция, докато по конвенция в C++ тя винаги е int функция, която връща 0 при успешно завършване на програмата...

Следващото - имената на променливите. M, N, a, brDigits!? Първо, тези имена въобще не са описателни и ме правят да изглеждам добър по състезателно програмиране (а не съм, наистина), а второ си позволяват и някаква странна смесица от български и английски в едно име. 

Правилото е, че имената на променливите трябва да са достатъчно описателни, за да не се налага да бъдат коментирани след това (кодът се самодокументира). Освен това - никога не слагайте български имена. Обожавам примера от книгата на Светлин Наков - представете си, че виетнамец ви чете кода и се чуди какво по дяволите е "br" (идва от "брой" и чувствам, че има нужда да го обясня, защото дори на български е неясно). А сега си представете, че вие четете кода на виетнамеца, който е използвал малко виетнамски в имената на променливите... не бъдете този гадняр.

Само английски имена и при това описателни! Например "numberOfDigits" или "digitCount", но никога тази пихтия горе!

Следващ проблем - обхватът на променливите. Декларирам M и i, хубаво, но ги ползвам много по-надолу. Колкото по-близко до първото им използване са декларирани променливите, толкова по-добре. Това е едно от правилата, които изглеждат безсмислени, но тяхната стойност става явна когато видите някой по-сложен проект, състоящ се от много много код.

Особено променлива за брояч във for цикъл... просто декларацията й няма работа извън самия цикъл.

И последно - някои по-дребни, но все пак съществуващи проблеми. 

Защо да не използвам динамичен масив вместо статичен? Защо просто не преброя колко са цифрите на числото и след това да си заделя точно толкова памет колкото ми трябва, вместо да предполагам, че ще са 30 (това няма и как да стане с типа int)...

Последно - коментарите! Излишни са! М е цяло число... уау, наистина ли? Кое го издаде, типа му int или факта, че има най-лошото име на променлива в историята? Просто такива коментари запълват кода с излишен текст и нямат работа там. Вместо да ги пиша, по-добре би било да измисля по-разумно име на променливата, което само по себе си обяснява каква стойност се съдържа в нея.


Тук забележките са по-малко, но пак ги има!

Отново нещо за коментарите - те също трябва да са само и единствено на АНГЛИЙСКИ! Това е единственият универсален език в света на програмирането. Точка.

В условието на while цикъла е хубаво да има интервали, за да може кода да е по-четим. Отново, това няма значение в такава дребна ситуация, но какво става ако условието беше:

 
Отговорът е "боза". Интервали, интервали (и скоби) - те са ваши приятели и правят кода много по-четим!

Някой други дреболийки. Бях написал статия за преинкрементирането на брояча във for цикли - има значение, защото дяволът се крие в детайлите! ++i e по-добре от i++.

Последно - в повечето програми на C++, най-добре е отварящата скоба { да е на същия ред, в който е условието на цикъла (но, разбира се, най-добрата практика е да си ПОСТОЯНЕН в стила, който ползваш и той да съответства на стила на хората, с които работиш).


Тук главоболията пак са в пълна сила, но за радост стигнахме края на програмата! 😅

Първото, което ми прави неприятно впечатление, е индентацията. Използвайте този Tab клавиш, но го ползвайте правилно! Тези условни конструкции долу... част от цикъла ли са? Ами не са!

Самият цикъл е трагедия. Ако погледнете този странен for цикъл отблизо, ще забележите, че той всъщност няма тяло. Дори това да е валидно, много по-добре е тялото му да бъде заградено от { и }. По-четим код и всички са щастливи накрая!

И накрая... празни редове. Празните редове всъщност са полезен инструмент когато разграничават отделните части от логиката, за да може кодът да стане по-четим, но тук... 4 реда преди _getch()? Няма смисъл и просто показва едно несериозно отношение на програмиста.

---

Вижте само колко много глупави грешки и то в такава проста програма! Самата логика на програмата почти не посмях да я коментирам, но със сигурност виждате някои прозорци за оптимизация и там.

Сигурен съм, че след време ще се смея и на сегашната си "прозорливост" в програмирането. Просто с времето ставаме по-добри, защото знаем повече и сме правили повече грешки.

А сега отивайте да трупате провали и да ставате ПО-ДОБРИ. 😉

Peace.

2 коментара:

  1. Определено в първи курс не се замислях над повечето забележки, които си посочил и просто хамалската преписвах, докато след това разбрах как става. Радвам се че ми припомни първата година в РУ специалност КН :D Поздрави и пожелание за upgrade code style :)

    ОтговорИзтриване