Menu

Funkcje w C++: deklaracja, definicja i wywołanie (z przykładami)

Jak pisać funkcje w C++: budowa z typem zwracanym, nazwą i parametrami, deklaracje a definicje, zwracanie wartości, funkcje void oraz pułapki, takie jak brakujący return i zapomniane prototypy.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Po co istnieją funkcje

Funkcja to nazwany blok kodu, który możesz uruchomić na żądanie, wywołując go. Zamiast powtarzać tę samą logikę w kilku miejscach, piszesz ją raz, nadajesz jej nazwę i wywołujesz tę nazwę wszędzie, gdzie jej potrzebujesz. Dzięki temu programy są krótsze, czytelniejsze i łatwiejsze do poprawiania: zmieniasz logikę w jednym miejscu, a każde wywołanie dostaje aktualizację.

Przez cały czas wywołujesz już jedną funkcję: main. To punkt wejścia, od którego zaczyna się każdy program w C++. Teraz napiszesz własne. Pętle, które pojawiły się wcześniej, jak for po zakresie, często żyją wewnątrz funkcji, dzięki czemu cały fragment logiki można ponownie wykorzystać po nazwie.

Budowa funkcji

Każda funkcja ma cztery części: typ zwracany, nazwę, listę parametrów w nawiasach i ciało w klamrach.

int add(int a, int b) {   // typ zwracany | nazwa | parametry
    return a + b;         // ciało
}
  • int to typ zwracany: rodzaj wartości, którą funkcja oddaje.
  • add to nazwa, której używasz do wywołania.
  • (int a, int b) to parametry: dane wejściowe, które dostarcza wywołujący.
  • Klamry zawierają ciało, czyli kod wykonywany przy wywołaniu.

Oto ta funkcja w kompletnym programie. Zdefiniowanie jej nad main sprawia, że main ją widzi w chwili wywołania.

Wywołanie add(2, 3) uruchamia funkcję z a = 2 i b = 3, a całe wyrażenie staje się zwróconą wartością. Możesz ją zapisać w zmiennej albo użyć bezpośrednio w innym wyrażeniu, jak w drugiej linii z cout.

Zwracanie wartości

Instrukcja return robi dwie rzeczy: oddaje wartość wywołującemu i natychmiast kończy funkcję. Kod po wykonanym return się nie wykonuje: sterowanie wraca prosto do miejsca, w którym wywołano funkcję.

Typ zwracanej wartości musi pasować do zadeklarowanego typu zwracanego (albo dać się na niego skonwertować). Funkcja zadeklarowana jako int powinna zwracać int; niezwrócenie niczego albo dotarcie do końca bez return to błąd w każdej funkcji innej niż void.

Funkcje void

Nie każda funkcja wytwarza wartość. Gdy funkcja po prostu coś robi (wypisuje dane, aktualizuje stan), jej typ zwracany to void. Funkcja void może użyć gołego return;, aby wyjść wcześniej, albo po prostu dojść do zamykającej klamry.

Próba użycia wyniku funkcji void, czyli int x = greet("Ada");, to błąd kompilacji, bo nie ma wartości do przypisania. Częsta pomyłka to pisanie return someValue; wewnątrz funkcji void; to również kompilator odrzuci.

Deklaracje a definicje

C++ czyta plik od góry do dołu, więc domyślnie funkcja musi pojawić się przed kodem, który ją wywołuje. Gdy taka kolejność jest niewygodna, dzielisz funkcję na deklarację (zwaną też prototypem) i definicję.

Deklaracja podaje sygnaturę funkcji i kończy się średnikiem, bez ciała. Obiecuje kompilatorowi: "ta funkcja istnieje, a tak się ją wywołuje". Pełna definicja może się wtedy pojawić później, nawet po main.

Bez prototypu w linii 4 kompilator natrafiłby na square(5) wewnątrz main, zanim w ogóle zobaczyłby square, i kompilacja by się nie powiodła. Prototypy to także sposób, w jaki pliki nagłówkowe pozwalają wielu plikom źródłowym współdzielić te same funkcje. Zauważ, że nazwy parametrów w deklaracji są opcjonalne: int square(int); działa równie dobrze, bo dla kompilatora liczą się tylko typy.

Częste błędy

Kilka pułapek łapie początkujących raz za razem:

  • Wywołanie przed deklaracją. Jeśli dostajesz błąd "add was not declared in this scope", funkcja jest zdefiniowana poniżej pierwszego wywołania i nie ma prototypu. Przenieś definicję wyżej albo dodaj prototyp.
  • Zapomniany return. Dotarcie do końca funkcji innej niż void bez return to niezdefiniowane zachowanie: wywołujący dostaje śmieci. Kompiluj z włączonymi ostrzeżeniami (-Wall), a kompilator to wychwyci.
  • Definicja a wywołanie. Definicja ma ciało w klamrach i nie ma końcowego średnika. Deklaracja ma średnik i nie ma ciała. Pomylenie ich, na przykład postawienie średnika zaraz po liście parametrów funkcji, którą chcesz zdefiniować, daje mylące błędy.
  • Ignorowanie wartości zwracanej. add(2, 3); w osobnej linii się skompiluje, ale obliczona suma zostanie po cichu wyrzucona. Upewnij się, że naprawdę wykorzystujesz to, co zwraca funkcja.
// Wygląda jak definicja, ale zbędny ; zamienia to w
// deklarację, po której zostaje osierocony blok: częsta literówka:
int triple(int n);   // <- ten ; kończy instrukcję
{
    return n * 3;    // n jest tu niezdefiniowane; ten blok jest teraz osierocony
}

Dalej: parametry funkcji

Widać już, że funkcje przyjmują dane przez listę parametrów, ale to dopiero początek. Następna strona omawia parametry funkcji: przekazywanie przez wartość i przez referencję, argumenty domyślne, parametry const i to, jak ten wybór decyduje, czy twoja funkcja może zmienić dane wywołującego.

Najczęściej zadawane pytania

Jak napisać funkcję w C++?

Nadaj jej typ zwracany, nazwę, nawiasy na parametry i ciało w klamrach: int add(int a, int b) { return a + b; }. Wywołujesz ją po nazwie z argumentami, na przykład add(2, 3). Jeśli funkcja niczego nie zwraca, użyj void jako typu zwracanego.

Jaka jest różnica między deklaracją a definicją funkcji w C++?

Deklaracja (albo prototyp) podaje kompilatorowi nazwę funkcji, typ zwracany i parametry i kończy się średnikiem: int add(int a, int b);. Definicja zawiera dodatkowo ciało w klamrach. Możesz zadeklarować funkcję przed main, a zdefiniować ją później: deklaracja pozwala wywołać funkcję, zanim pojawi się definicja.

Co się stanie, gdy funkcja w C++ nie zwróci wartości?

W przypadku funkcji void nic: po prostu się kończy. Ale dla funkcji innej niż void dotarcie do końca bez return to niezdefiniowane zachowanie: wywołujący dostaje śmieciową wartość, a program może działać błędnie. Większość kompilatorów ostrzega o tym; w funkcji innej niż void zawsze zwracaj wartość na każdej ścieżce.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ