Programowanie. Teoria i praktyka z wykorzystaniem C++
Programowanie. Teoria i praktyka z wykorzystaniem C++
Programowanie. Teoria i praktyka z wykorzystaniem C++
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
6.5. ZAMIANA GRAMATYKI W KOD 197<br />
}<br />
return left + expression(); // Wczytuje wyraenie i sprawdza jego warto,<br />
// a nastpnie wykonuje dodawanie.<br />
case '–':<br />
return left – expression(); // Wczytuje wyraenie i oblicza jego warto,<br />
// a nastpnie wykonuje odejmowanie.<br />
default:<br />
return left;<br />
// Zwraca warto skadnika.<br />
}<br />
To jako dziaa. Wypróbowalimy ten kod w ukoczonym programie i stwierdzilimy, e przetwarza<br />
wszystkie poprawne wyraenia (i ani jednego niepoprawnego). W wikszoci przypadków<br />
nawet zwraca prawidowe wyniki. Na przykad wyraenie 1+2 jest wczytywane jako skadnik<br />
(o wartoci 1), po którym jest znak + i wyraenie (które w tym przypadku jest skadnikiem<br />
o wartoci 2) — zwracany wynik to 3. Analogicznie dla wyraenia 1+2+3 zwracana jest warto 6.<br />
Moemy dugo cign list przypadków, w których kod ten zwraca prawidowe wyniki, ale<br />
do rzeczy — co stanie si z wyraeniem 1-2-3? Funkcja expression() wczyta 1 jako skadnik<br />
i przejdzie do 2-3 jako wyraenia (skadajcego si ze skadnika 2 i wyraenia 3). Nastpnie<br />
odejmie warto wyraenia 2-3 od 1. Innymi sowy obliczy warto wyraenia 1-(2-3), która<br />
wynosi 2 (liczba dodatnia). Nas jednak w szkole uczono (a moe i wczeniej), e 1-2-3 oznacza<br />
tyle, co (1-2)-3, a wic wynik powinien by -4 (liczba ujemna).<br />
W ten sposób utworzylimy bardzo fajny program, który nie robi tego, co trzeba. Sytuacj<br />
pogarsza fakt, e w wielu przypadkach zwraca prawidowy wynik. Na przykad dla wyraenia<br />
1+2+3 zostanie zwrócony wynik 6, poniewa 1+(2+3) jest równowane z (1+2)+3. Jaki by nasz<br />
podstawowy z programistycznego punktu widzenia bd? Zawsze naley zada sobie to pytanie,<br />
gdy znajdzie si bd. Dziki temu bdzie mona unikn powtórzenia go innym razem.<br />
Naszym problemem jest to, e popatrzylimy na kod i postanowilimy zgadywa. To rzadko<br />
wystarcza! Musimy rozumie, co robi nasz kod, i umie wyjani, czemu robi to, co trzeba.<br />
Ponadto analizowanie bdów jest czsto najlepszym sposobem na znalezienie poprawnego<br />
rozwizania. Nasza funkcja expression() szuka najpierw skadnika, a nastpnie, jeli znajduje si<br />
za nim znak + lub -, wyraenia. Jest to w rzeczywistoci implementacja nieco innej gramatyki:<br />
Expression:<br />
Term<br />
Term '+' Expression // dodawanie<br />
Term '–' Expression // odejmowanie<br />
Rónica midzy t a nasz gramatyk polega na tym, e my chcielimy, aby wyraenie 1-2-3 byo<br />
traktowane jako wyraenie 1-2, po którym jest znak - i skadnik 3. Natomiast uzyskalimy<br />
skadnik 1, po którym znajduje si znak - i wyraenie 2-3. Innymi sowy chcielimy, aby 1-2-3<br />
oznaczao (1-2)-3, a nie 1-(2-3).<br />
Tak, debugowanie bywa mudne, trudne i czasochonne, ale w tym przypadku pracujemy<br />
nad zasadami wyuczonymi w podstawówce. Sk w tym, e musimy „wpoi” je komputerowi,<br />
który uczy si znacznie wolniej od nas.<br />
Zauwa, e moglibymy zdefiniowa 1-2-3 jako 1-(2-3) zamiast (1-2)-3 i unikn caej<br />
tej dyskusji. Czsto najtrudniejszymi problemami w programowaniu s zasady, które zostay<br />
ustalone dla ludzi wiele lat przed tym, jak zaczlimy uywa komputerów.