====== Pisanie programów ======
Oto kilka rad i wskazówek dotyczących pisania i komentowania kodu:
* [[#Komentowanie_kodu|Komentowanie kodu]]
* [[#Obsluga_wyjatkow|Obsługa wyjątków]]
====== 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 {{:pl:dydaktyka:jimp2:2016:part2:org: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(...)