Na co musí myslet programátor
- syntax (pohlídat si středníky apod. aby to šlo zkompilovat) – viz ZPRO, PRC
- správné formátování (např. odsazování, max 1 příkaz na řádek)
- vhodné strukturování kódu s ohledem na pochopitelnost, údržbu a rozšiřitelnost (to se budeme učit a procvičovat na PROP)
- nedefinované chování
nebezpečí: může se projevit libovolným způsobem (může to nějak fungovat ale špatně, může to dávat nedefinovaný nebo i náhodný výsledek, může to crashnout program, ale může to třeba taky zformátovat disk, restartovat počítač atd.) -
správnost algoritmu (dostatečná obecnost)
- ošetřit chování pro všechny možné vstupy (včetně těch, se kterými programátor nepočítal – „blbost uživatele“)
- demonstrovat na příkladu výpočtu odmocniny půlením intervalu – pro \(x>1\) se půlí interval \((0, x)\), pro \(x<1\) se půlí interval \((x, 1)\) (a pro \(x<0\) chyba – viz níže)
-
počítat s aritmetickými chybami pro číselné typy s plovoucí desetinnou tečkou (float, double)
např. pro ukončení cyklu není vhodná podmínka == nebo !=, ale >= nebo <=, např.float x = 0; float h = n / 1000.0; while (x != n) { // do something x += h; }
-
také pozor na porovnávání bezznaménkových (unsigned) typů s nulou:
template <typename Value, typename Index> void f(Value* array, Index N) { for (Index i = N - 1; i >= 0; i--) { // do something array[i] = 0; } }
pokud je
Index
např.unsigned int
, je podmínka v cyklu vždy splněna, neb0-- == 4294967295
-
psaní komentářů a případně dokumentace (zpětné dopisování textu je nejotravnější věc, která může programátora potkat)
- efektivita výsledného kódu
- výběr vhodných datových struktur – včetně kontejnerů z STL (např.
std::vector
vsstd::set
vsstd::unordered_set
) - výběr vhodných algoritmů
- optimalizace samotného kódu – umožňují zpracovat ekvivalentní program (z hlediska výpočtu) efektivněji
- výběr vhodných datových struktur – včetně kontejnerů z STL (např.
Zpracování chyb
Možnosti:
- speciální hodnoty (např.
NULL
,NaN
apod) – používá se např. v databázích (nezávisle na jazyku), matematických funkcích (C i C++) - chybové kódy (error codes) – přístup jazyka C
- výjimky – musí to podporovat jazyk (C++ ano, C ne)
std::variant
- assert + crash – hodí se pro debugování a pro chyby, ze kterých se nelze zotavit
- např.
operator[]
pro pole/vektory – ověřování se chceme vyhnout z důvodu efektivity - assert se velmi hodí i pro případy, kdy se programátor zrovna nechce danou chybou zabývat – omezíme si přípustnou množinu správných vstupů a správné zpracování chyb v podstatě odložíme na později (až assert nebude stačit – dle výčtu výše)
- např.