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 = 1....
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 = 1. Jaki wynik zostanie zwrócony?
A. 7
B. 4
C. 13
D. 1
Pytanie z egzaminu CKE, styczeń 2021 (arkusz EE.09-SG-21.01).
Wynik 13 jest prawidłowy, bo trzeba dokładnie prześledzić działanie pętli while i operatora przypisania z dodawaniem +=. Funkcja dostaje argument $Z = 1. Warunek pętli to $Z < 5, więc dla wartości 1 pętla się wykona. Instrukcja $Z += 2 * $Z + 1 oznacza to samo co $Z = $Z + (2 * $Z + 1). W PHP mnożenie ma wyższy priorytet niż dodawanie, więc najpierw liczone jest 2 * $Z. Dla $Z = 1 mamy: $Z = 1 + (2 * 1 + 1), czyli $Z = 4. Warunek jest sprawdzany ponownie: 4 < 5, więc pętla działa drugi raz. Teraz $Z = 4 + (2 * 4 + 1), czyli 4 + 9 = 13. Następne sprawdzenie daje 13 < 5, co jest fałszem, więc funkcja zwraca 13. Z mojego doświadczenia takie zadania najlepiej robić tabelką: wartość przed iteracją, warunek, obliczenie, wartość po iteracji. To dobra praktyka także przy debugowaniu kodu PHP, bo pętle bardzo łatwo robią błędy logiczne albo wpadają w nieskończone wykonanie. W prawdziwych projektach webowych podobne konstrukcje pojawiają się np. przy przeliczaniu liczników, paginacji, limitów prób logowania czy obróbce danych z formularza. Warto też pamiętać, że zmienne w PHP są rozróżniane wielkością liter, więc $Z i $z to nie to samo, co czasem potrafi nieźle namieszać.
W tym zadaniu najczęstszy błąd polega na zbyt szybkim czytaniu instrukcji w pętli i potraktowaniu jej tak, jakby wykonała się tylko raz albo jakby operator += działał inaczej niż w PHP. Funkcja nie zwraca wartości 1, ponieważ pętla while na początku sprawdza warunek $Z < 5, a dla argumentu startowego $Z = 1 ten warunek jest spełniony. Kod w klamrach musi więc zostać wykonany przynajmniej jeden raz. Nie można też zatrzymać się na wartości 4, bo po pierwszym obliczeniu $Z faktycznie wynosi 4, ale pętla while nie kończy się automatycznie po jednej iteracji. Warunek jest sprawdzany ponownie i 4 nadal jest mniejsze od 5, więc następuje druga iteracja. Wartość 7 zwykle wychodzi wtedy, gdy ktoś odczyta zapis $Z += 2 * $Z + 1 jako zwykłe przypisanie $Z = 2 * $Z + 1. To jest inna operacja. Operator += dodaje wynik prawej strony do aktualnej wartości zmiennej, czyli działa jak $Z = $Z + wyrażenie. Dodatkowo trzeba pilnować priorytetów operatorów: mnożenie wykonuje się przed dodawaniem. Poprawny przebieg to 1 → 4 → 13, a potem pętla kończy działanie, bo 13 < 5 jest fałszem. Moim zdaniem przy takich fragmentach kodu nie warto liczyć w głowie na skróty. Lepiej rozpisać każdą iterację, bo to jest dokładnie ta sama metoda, której używa się potem przy analizie błędów w aplikacjach PHP, na przykład gdy licznik rekordów, koszyk zakupowy albo algorytm naliczania rabatu daje dziwne wyniki.