16.07.2014 Views

Programowanie. Teoria i praktyka z wykorzystaniem C++

Programowanie. Teoria i praktyka z wykorzystaniem C++

Programowanie. Teoria i praktyka z wykorzystaniem C++

SHOW MORE
SHOW LESS

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.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!