czwartek, 18 lutego 2016

Zasady pisania zrozumiałego i czytelnego kodu

Ten post będzie zawierał wskazówki oraz zasady jakimi należy się kierować, aby przygotować maksymalnie czytelny i zrozumiały kod, nie tylko dla innego użytkownika, ale też dla autora gdy przyjdzie mu po dłuższym czasie do niego zaglądnąć.

Podstawowe zasady


Przy pisaniu kodu programu należy pamiętać o kilku bardzo istotnych elementach:

Zmienne stosowane w programie powinny być o możliwie jak najmniejszym zasięgu. Oznacza to, że jeżeli jest ona potrzebna tylko w jednej funkcji, to zostaje zdeklarowana tylko w niej. Nie należy jej deklarować tak aby była dostępna dla całego programu. Dzięki takiemu zabiegowi kod jest mniejszy przez co wykonuje się szybciej ponieważ nie wykorzystuje pamięci ram tylko bezpośrednio rejestry układu.



Kod powinien być czytelny, najlepiej stosować komentarze, przynajmniej przed istotnymi jego elementami. Należy także pamiętać o tym aby był on możliwie najprościej napisany. Dzięki temu będzie on nie tylko bardziej czytelny ale też jego wykonanie przejdzie szybciej.

Kompilatorowi należy przekazywać możliwie jak najwięcej istotnych informacji, czyli jeśli zmienna zostaje zdeklarowana, to dodatkowo trzeba ją opisać odpowiednim modyfikatorem np. const, volatile czy static. Oczywiście tylko wtedy gdy taki modyfikator pasuje do deklarowanej zmiennej. Dzięki temu, że kod będzie lepiej zdefiniowany to pozwoli to na uzyskanie mniejszego oraz szybciej wykonanego kodu wynikowego. Dodatkowo pomięcie modyfikatora volatile może utrudnić poprawne wykonanie programu, zwłaszcza jeśli chodzi o przerwania.

Jeśli wykorzystuje się dwa języki programowania np C i Asembler wtedy nie należy ich mieszać razem w jednej funkcji. Tutaj powód jest dosyć prosty, gdy program jest napisany w języku C to kompilator dokonuje na nim odpowiedniej optymalizacji całego kodu. Gdy natomiast część takiej funkcji zostanie napisana w asemblerze spowoduje to jej pomięcie w procesie.

Ostatnim elementem jest stosowanie zmiennych odpowiednich dla danej architektury, np. układy 32 bitowe lepiej sobie radzą z zmiennymi też 32 bitowymi.


Składnia


Kolejnym elementem są pewne zasady jakich warto przestrzegać w trakcie tworzenia kodu:

  • Stosowanie nawiasów klamrowych przy instrukcjach warunkowych czy pętlach takich jak if, else, switch, while, do, for. Nawet dla pojedynczej linii kodu. 
  • Już wymienione wcześnie używanie modyfikatorów const, static, volatile: 
    • Jeśli chodzi o const to należałoby go stosować do tworzenia stałych, jako argument funkcji aby zaznaczyć, że przekazywany argument nie będzie zmieniany, do zaznaczenia, że dane pole jest tylko do odczytu oraz jako alternatywny zapis zamiast #define. Dzięki takiemu zabezpieczeniu kompilator poinformuje użytkownika, że nastąpiła próba zapisu do zmiennej przeznaczonej tylko do odczytu.
    • Static natomiast zostanie zastosowany modyfikator static, dzięki niemu zmienna będzie mogła być wywołana w funkcji w której została zdefiniowana. Pozwoli to na zmniejszenie liczby niepotrzebnych interakcji pomiędzy różnymi elementami programu.
    • Co się tyczy volatile, to jak już wspomniałem, należy ją stosować do obsługi przerwań, jako zmienne które mogą być wykorzystane przez dwie działające jednocześnie funkcje, oraz jako wskaźnik do rejestru peryferiów. Dzięki odpowiedniemu użyciu tego modyfikatora eliminuje się błędy związane z nieodpowiednim usunięciem operacji zapisu i odczytu danej zmiennej w procesie optymalizacji programu.
  • Komentarz stosowany jest tylko i wyłącznie do komentowania kodu. Nie należy go stosować w celu usunięcia tymczasowo fragmentu kodu ponieważ stwarza to pewne zagrożenie, dotyczące skompilowania niechcianego fragmentu programu. 
  • Wykorzystywanie typów zdefiniowanych w standardzie C99 do liczb całkowitych. Dzięki temu będzie mniej problemów gdy kod będzie przenoszony na inny układ z inną architekturą. W tym punkcie chodzi o zastąpienie takich nazw jak int czy long zmiennymi oznaczonymi jako uint8_t, uint_32 bez znaku bądź np. int8_t czy int32_t ze znakiem. 
  • Do typów signed, jest to typ ze znakiem, nie należy stosować operatorów bitowych. Może to spowodować to, że na różnych kompilatorach nie zostanie otrzymana ta sama wartość liczby. Ponieważ sposób prezentacji liczb ujemnych nie został opisany w standardzie.
  • Nie należy mieszać signed i unsigned w jednym wyrażeniu. Podobnie jak w poprzednim punkcie, nie zostały liczby ze znakiem opisane w standardzie, co może prowadzić do powstania błędów
  • Nie należy stosować przecinków przy deklarowaniu zmiennych. W tym przypadku program jest bardziej czytelny i zrozumiały, zwłaszcza dla innego programisty.

To są tylko podstawowe informacje dotyczące poprawnego tworzenia zrozumiałego i przejrzystego kodu, ale na pewno mogą poprawić jakoś oraz możliwość zrozumienia napisanego programu.