W języku C++ funkcja zwracająca wynik potęgowania, działająca na dwóch parametrach wejściowych: liczbie x i wykładniku w, ma deklarację
A. int potega(int x);
B. int potega(int x, int w);
C. void potega(int x, int w);
D. void potega(int x, int w, int wynik);
Pytanie z egzaminu CKE, czerwiec 2019 (arkusz EE.09-X-19.06).
Deklaracja int potega(int x, int w); jest właściwa, bo dokładnie opisuje funkcję, która ma przyjąć dwa parametry wejściowe i zwrócić obliczony wynik. W C++ zapis deklaracji funkcji składa się z typu zwracanego, nazwy funkcji oraz listy parametrów w nawiasach. Tutaj int przed nazwą oznacza, że funkcja oddaje wartość całkowitą, czyli np. wynik potęgowania 2³ może zwrócić jako 8. Parametry int x oraz int w oznaczają podstawę potęgi i wykładnik, więc funkcja ma komplet danych potrzebnych do obliczenia $x^w$. W praktyce taka funkcja mogłaby wyglądać tak: int wynik = potega(2, 5); i wtedy zmienna wynik przechowa 32. Moim zdaniem to jest najczytelniejsza wersja, bo od razu widać zamiar programu: podajemy dane, dostajemy rezultat. To też pasuje do dobrych praktyk C++: funkcja, która coś oblicza, powinna najczęściej zwracać wynik przez return, a nie mieszać obliczenia z wypisywaniem albo sztucznie przekazywać wynik jako parametr. Oczywiście w prawdziwym kodzie trzeba jeszcze uważać na zakres typu int, bo duże potęgi szybko powodują przepełnienie liczby całkowitej.
W tym pytaniu kluczowe jest rozróżnienie między parametrami wejściowymi a wartością zwracaną przez funkcję. Funkcja potęgująca potrzebuje dwóch informacji: podstawy, czyli x, oraz wykładnika, czyli w. Jeśli deklaracja zawiera tylko int x, to funkcja nie wie, do jakiej potęgi ma podnieść liczbę. Można by teoretycznie założyć jakiś stały wykładnik w środku funkcji, ale to już nie spełnia treści zadania, bo mowa jest o dwóch parametrach wejściowych. Częsty błąd polega tu na skupieniu się tylko na nazwie funkcji, a nie na jej pełnym nagłówku. Sama nazwa potega nie wystarczy, trzeba jeszcze poprawnie określić interfejs funkcji. Deklaracje z void też nie pasują do funkcji, która ma zwracać wynik. Typ void oznacza, że funkcja nic nie zwraca przez instrukcję return, więc nie da się wygodnie napisać na przykład int a = potega(3, 4);. Taka funkcja mogłaby co najwyżej wypisywać wynik na ekran, ale to jest inna odpowiedzialność i raczej gorszy projekt przy funkcji obliczeniowej. Wariant z dodatkowym parametrem wynik również jest mylący. Jeżeli wynik jest przekazany jako zwykły int, to w C++ trafia do funkcji kopia tej zmiennej, więc zmiana parametru w środku nie zmieni wartości u wywołującego. Dałoby się użyć referencji, np. int& wynik, albo wskaźnika, ale nadal byłby to styl mniej naturalny dla prostego obliczenia. Z mojego doświadczenia najlepiej zapamiętać zasadę: dane potrzebne do obliczeń idą w parametrach, a rezultat obliczeń wraca przez typ zwracany funkcji.