Pisanie programów

Oto kilka rad i wskazówek dotyczących pisania i komentowania kodu:

Komentowanie kodu

  • Wszystkie deklaracje funckji, deklaracje oraz definicje klas, w przypadku wielomodułowych programów staramy się umieszczać w pliku nagłówkowym. Staramy się unikać używania dyrektywy #include w plikach nagłówkowych, chyba że jest to niezbędne lub zamierzone.
  • Pliki nagłówkowe powinny zawierać tylko niezbędne deklaracje oraz definicje.
  • Pliki nagłówkowe powinny być zabezpieczone przed wielokrotną kompilacją:
#ifndef PLIKH
#define PLIKH
 
// treść pliku nagłówkowego
 
#endif
  • Dyrektywą #include włączamy tylko pliki nagłówkowe. Niewolno włączać plików *.c, *.cpp.
  • Dla zwiększenia przejrzystości, szczególnie dużych plików (ponad 300 linii kodu) warto stosować dodatkowe separatory pomiędzy częściami kodu np. pomiędzy funkcjami:
/// \brief opis funckji func1
///
/// \param  __i - opis parametru __i
/// \param  __f - opis parametru __f
/// \return funkcja zwraca:
/// \li 0 - w przypadku gdy...
/// \li 1 - w przypadku gdy...
/// \li 2 - w przypadku gdy...
int func1(int __i, float  __f)
{
     // Ciało funckji
}
// ----------------------------------------------------
 
/// \brief opis funckji func2
///
/// \return brak zwracanych wartosci
void func2(void)
{
     // Ciało funckji
}
// ----------------------------------------------------
 
 
/// \brief opis funckji func3
///
/// \param __f_ptr - opis parametru __f_ptr
/// \return znak ktory reprezentuje
char func3(char(* __f_ptr)(int, float*& __in_ptr_ref))
{
     // Ciało funckji
}
// ----------------------------------------------------
  • Należy stosować jak najwięcej komentarzy. Krytyczne miejsca programu muszą być komentowane.
  • Dodatkowym atutem, wpływającym na jakość tworzonego kodu jest stosowanie komentarzy zgodnych ze specyfikacją wymaganą przez Doxygen. Oto przykład komentarzy dla pliku nagłówkowego:
/**
* \file nazwapliku.h
* \author Imie i Nazwisko
* \date 1.10.2008
* \version 1.0
* \brief Krótki opis co plik zawiera
*/
// -------------------------------------------------------------------------
 
#ifndef PLIKH
#define PLIKH
// -------------------------------------------------------------------------
 
/**
* \class klasa
* \author autor
* \date 1.10.2008
* \brief Krótki opis klasy
*/
class klasa
{
      private:
 
      int f1;     ///< opis pola klasy
      int f2;     ///< opis pola klasy
      float f1; ///< opis pola klasy
 
      public:
 
      /// \brief Konstruktor domyślny klasy
      klasa(void);
 
      /// \brief Konstruktor klasy
      ///
      /// \param f - opis parametru
      klasa(int f);
 
      /// \brief opis metody 1
      ///
      /// \param _a - opis parametru
      /// \param *c - opis parametru
      /// \return opis zwracanej wartości
      int metoda1(int _a, double* c);
};
// -------------------------------------------------------------------------
#endif

Komentarze zgodne z Doxygen stosujemy tylko raz np. tylko w pliku nagłówkowym. Można a nawet trzeba sporządzać także komentarze „robocze”, które nie będą uwzględniane przez narzędzie, szczególnie w najważniejszych miejscach programu.

  • Staramy się robić wcięcia, dla kolejnych poziomów zagnieżdżeń kodu. Standartowo 3-5 spacji.
  • Nie używamy znaku tablulacji:
    • ponieważ powoduje to problem w przejrzystości kodu otwartego w innych edytorach niż ten w którym był pisany;
    • z powyższego powodu konfigurujemy edytor tak aby zamieniał znak tabulacji na spacje;
    • jeżeli edytor nie posiada takiej opcji to najwyższy czas go zmienić;

Obsługa wyjątków

Podczas pisania programów w ramach zajęć należy stosować mechanizmy obsługi sytuacji wyjątkowych. Poniżej zaproponowany sposób pozwoli na stworzenie kodu który w tym kontekście będzie prawidłowo przechodził testy.

  • Ściągnij plik aghexception.tar.gz który zawiera definicję klasy przeznaczonej do obsługi sytuacji wyjątkowych.
  • Klasa ma już gotowe metody które są gotowe do użycia.
  • Jeżeli chcesz możesz tworzyć swoje klasy do obsługi błędów jednak aby mogły one poprawnie przechodzić testy muszą one dziedziczyć podaną klasę aghException w sposób publiczny.
  • Niezastosowanie tej klasy do obsługi błędów będzie skutkowało możliwymi błędami podczas testów które w takim wypadku nie będą mogły zostać usprawiedliwione.

Jak używać

Poniżej prosty przykład użycia klasy.
Mamy prostą funkcję getValue która zwraca wartość znajdującą się w tablicy _tab na miejscu o indeksie przesłanym jako argument. Jeżeli wartość indeksu jest nieprawidłowa (tzn. poza zakresem tablicy) to w takim wypadku najlepszym rozwiązaniem jest wyrzucenie wyjątku (throw).

int& aghVector::getValue(int _index) const
{
  if((_index < 0) || (_index >= size()))
    throw aghException(0, "Index out of range", __FILE__, __LINE__);
  return _tab[_index];
}

W powyższym przykładzie wykorzystana jest klasa aghException. Aby obsłużyć tak wyrzucony wyjątek np. w funkcji main robimy tak:

  try
    {
      v->getValue(-1) = 6;
    }
  catch(aghException& e)
    {
      cout << e << endl;
    }
  catch(...)    
    {
      cout << "\nUnrecognized error\n";
    }

W tym przypadku obsługa wyjątku zostanie przekierowana do bloku:

catch(aghException& e)

i na ekranie pojawi się taki komunikat:

Error in aghVector.h file at 69 line.
Error code: 0 (Index out of range).

Natomiast wszystkie pozostałe błędy które nie są obsługiwane przez podaną klasę będą obsługiwane w bloku:

catch(...)
pl/dydaktyka/jimp2/2016/part2/org/codepolicy.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0