function policz($Z) { while($Z < 5) { $Z += 2 * $Z + 1; } return $Z; } Zapisaną językiem PHP funkcję o nazwie policz wywołano z argumentem $Z = 2....
function policz($Z) { while($Z < 5) { $Z += 2 * $Z + 1; } return $Z; }Zapisaną językiem PHP funkcję o nazwie policz wywołano z argumentem $Z = 2. Jaki wynik zostanie zwrócony?
A. 2
B. 5
C. 13
D. 7
Wynik 7 wynika z dokładnego prześledzenia działania pętli while oraz operatora przypisania z dodawaniem, czyli +=. Funkcja startuje z argumentem $Z = 2. Warunek pętli brzmi: $Z < 5, więc dla wartości 2 jest spełniony. Wewnątrz pętli wykonuje się instrukcja $Z += 2 * $Z + 1. W PHP najpierw liczona jest prawa strona wyrażenia z aktualną wartością zmiennej: 2 * 2 + 1 = 5. Potem operator += dodaje ten wynik do dotychczasowego $Z, czyli 2 + 5 = 7. Po tej jednej iteracji $Z ma wartość 7, więc warunek $Z < 5 nie jest już spełniony i pętla się kończy. Funkcja zwraca 7. Moim zdaniem to dobry przykład, bo pokazuje typowy haczyk z operatorem +=: on nie zastępuje zmiennej samym wynikiem prawej strony, tylko dodaje ten wynik do obecnej wartości. W praktyce takie konstrukcje spotyka się np. przy zliczaniu punktów, aktualizacji kosztu koszyka, naliczaniu prowizji albo modyfikowaniu liczników w algorytmach. Dobra praktyka branżowa jest taka, żeby przy mniej oczywistych obliczeniach rozbijać kod na pomocnicze zmienne, np. $przyrost = 2 * $Z + 1; $Z += $przyrost;. Kod jest wtedy czytelniejszy i łatwiej go debugować, szczególnie w PHP, gdzie szybkie pomyłki w operatorach potrafią dać całkiem inne wyniki.
Niepoprawne odpowiedzi najczęściej wynikają z pomylenia dwóch rzeczy: obliczenia prawej strony wyrażenia oraz działania operatora +=. W tej funkcji nie wystarczy policzyć 2 * $Z + 1 i uznać tego za nową wartość zmiennej. Dla $Z = 2 prawa strona faktycznie daje 5, ale instrukcja $Z += 5 oznacza dokładnie to samo co $Z = $Z + 5. Dlatego końcowa wartość po pierwszym przebiegu pętli to 7, a nie 5. To jest dość częsty błąd, zwłaszcza gdy ktoś czyta += jak zwykłe przypisanie, a nie jak skrót od dodawania z przypisaniem. Warto też uważać na pętlę while. Warunek jest sprawdzany przed każdą iteracją, a nie po niej. Startowe 2 spełnia warunek $Z < 5, więc kod w pętli na pewno wykona się przynajmniej raz. Z tego powodu wynik 2 nie ma sensu, bo funkcja nie zwraca od razu argumentu wejściowego. Z kolei wynik 13 sugeruje, że ktoś wykonał pętlę jeszcze raz po uzyskaniu 7 albo źle potraktował warunek zakończenia. Po zmianie $Z na 7 warunek $Z < 5 jest fałszywy, więc druga iteracja nie następuje. Z mojego doświadczenia najlepsza metoda przy takich zadaniach to zrobić małą tabelkę: wartość przed pętlą, sprawdzenie warunku, obliczenie przyrostu, wartość po instrukcji. Tak właśnie programista analizuje kod podczas debugowania, niezależnie czy to PHP, JavaScript czy inny język z podobnymi operatorami.