Funkcje w C# – dziel i rządź

Nauczysz się tworzyć własne funkcje, przekazywać parametry i zwracać wartości. Zrozumiesz, dlaczego funkcje to podstawa dobrego programowania.

void return parametry ref overloading
01

Czym jest funkcja i po co nam?

Funkcja to wydzielony fragment kodu wykonujący konkretne zadanie. Można ją wywołać wielokrotnie z różnymi danymi.

Wyobraź sobie, że piszesz program, który 10 razy wyświetla powitanie. Bez funkcji musiałbyś skopiować ten sam kod 10 razy. Z funkcją – piszesz raz, wywołujesz 10 razy.

Przepis
funkcja
Składniki
parametry
Gotowanie
kod funkcji
Danie
return

Zalety używania funkcji

ZasadaCo oznacza?Przykład
DRYDon’t Repeat Yourself – nie powtarzaj koduZamiast 10× ten sam kod → 1 funkcja wywoływana 10×
CzytelnośćKod podzielony na małe kawałkiObliczPodatek() mówi więcej niż 20 linii obliczeń
TestowanieŁatwiej sprawdzić małą funkcjęTestujesz Dodaj(2,3) → oczekujesz 5
ReużywalnośćRaz napisane, używane wszędzieFunkcja SprawdzEmail() w wielu miejscach
02

Struktura funkcji

Każda funkcja składa się z kilku elementów. Poznaj schemat, który będziesz stosować zawsze.

cs/SchematFunkcji.cs C#
// Schemat ogólny:
[modyfikator] [typ zwracany] [NazwaFunkcji]([parametry])
{
    // ciało funkcji - kod do wykonania
    return [wartość];  // jeśli typ != void
}

// Przykład konkretny:
static int Dodaj(int a, int b)
{
    int wynik = a + b;
    return wynik;
}

Wyjaśnienie elementów

ElementCo to?Przykłady
staticModyfikator – funkcja należy do klasy, nie do obiektustatic, public, private
Typ zwracanyCo funkcja „oddaje” po zakończeniuint, string, bool, void
NazwaJak wywołujemy funkcję (PascalCase!)ObliczSume, SprawdzWiek
ParametryDane wejściowe w nawiasach(int a, int b), (string imie)
returnZwraca wartość i kończy funkcjęreturn wynik;
Dlaczego static?

Na tym etapie nauki wszystkie funkcje piszemy jako static. Dlaczego? Bo wywołujemy je z Main(), która też jest static. Bez static musielibyśmy tworzyć obiekt klasy – to temat na później (programowanie obiektowe).

Konwencja nazewnictwa

Nazwy funkcji piszemy PascalCase – każde słowo z wielkiej litery, bez spacji:
ObliczPodatek, SprawdzCzyPelnoletni, WypiszWynik
obliczpodatek, oblicz_podatek, obliczPodatek

03

Funkcje void (bez wartości zwracanej)

Funkcje void wykonują akcję, ale nic nie zwracają. Służą do wyświetlania, zapisywania, modyfikowania – ale nie „oddają” żadnej wartości.

Wywołanie
PowitajOsobe(„Anna”)
Wykonanie
Console.WriteLine
Koniec
nic nie zwraca

Przykład 1: Bez parametrów

cs/FunkcjaVoid.cs C#
// Definicja funkcji
static void PowitajUzytkownika()
{
    Console.WriteLine("Witaj w programie!");
    Console.WriteLine("Miłego dnia!");
}

// Wywołanie w Main():
PowitajUzytkownika();  // Wyświetli dwie linie
PowitajUzytkownika();  // Można wywołać wielokrotnie!

Przykład 2: Z parametrem

cs/FunkcjaZParametrem.cs C#
// Funkcja przyjmuje imię jako parametr
static void PowitajOsobe(string imie)
{
    Console.WriteLine($"Witaj {imie}!");
}

// Wywołania z różnymi argumentami:
PowitajOsobe("Anna");   // Witaj Anna!
PowitajOsobe("Marek");  // Witaj Marek!
PowitajOsobe("Ola");    // Witaj Ola!
Parametr vs Argument

Parametr – zmienna w definicji funkcji: string imie
Argument – konkretna wartość przy wywołaniu: "Anna"

04

Funkcje zwracające wartość

Te funkcje wykonują obliczenia i „oddają” wynik za pomocą słowa return. Wynik można zapisać do zmiennej lub użyć dalej.

Wywołanie
Dodaj(5, 3)
Obliczenie
5 + 3 = 8
return 8
zwraca wartość

Przykład 1: Funkcja matematyczna

cs/FunkcjaZwracajaca.cs C#
// Funkcja zwraca int – typ przed nazwą!
static int Dodaj(int a, int b)
{
    int wynik = a + b;
    return wynik;  // Zwraca wartość
}

// Wywołanie – wynik zapisujemy do zmiennej:
int suma = Dodaj(5, 3);
Console.WriteLine($"Suma: {suma}");  // Suma: 8

// Można też użyć bezpośrednio:
Console.WriteLine(Dodaj(10, 20));  // 30

Przykład 2: Funkcja zwracająca bool

cs/FunkcjaBool.cs C#
// Funkcja sprawdzająca warunek – zwraca true/false
static bool CzyPelnoletni(int wiek)
{
    return wiek >= 18;  // Zwraca wynik porównania
}

// Użycie w warunku if:
if (CzyPelnoletni(20))
{
    Console.WriteLine("Osoba jest pełnoletnia");
}

// Lub zapisanie do zmiennej:
bool pelnoletni = CzyPelnoletni(16);  // false

void – tylko działa

WypiszWynik(5);
Wyświetla coś, ale nic nie zwraca.
Nie można zapisać do zmiennej.

return – oddaje wartość

int x = Oblicz(5);
Zwraca wynik, który można zapisać, użyć w if, przekazać dalej.

Częsty błąd

Funkcja z typem int MUSI zwrócić int. Kompilator nie pozwoli skompilować funkcji bez return (lub z return złego typu).

05

Parametry funkcji

Funkcja może przyjmować wiele parametrów różnych typów. Poznasz też parametry domyślne i przekazywanie przez referencję.

Wiele parametrów różnych typów

cs/WieleParametrow.cs C#
static void WypiszDane(string imie, int wiek, double wzrost)
{
    Console.WriteLine($"Imię: {imie}");
    Console.WriteLine($"Wiek: {wiek}");
    Console.WriteLine($"Wzrost: {wzrost}m");
}

// Wywołanie – kolejność argumentów musi się zgadzać!
WypiszDane("Anna", 17, 1.65);

Parametry z wartością domyślną

Parametr domyślny ma przypisaną wartość już w definicji. Jeśli nie podasz argumentu, użyta zostanie wartość domyślna.

cs/ParametryDomyslne.cs C#
// "powitanie" ma wartość domyślną "Cześć"
static void WypiszPowitanie(string imie, string powitanie = "Cześć")
{
    Console.WriteLine($"{powitanie}, {imie}!");
}

// Różne sposoby wywołania:
WypiszPowitanie("Anna");                    // Cześć, Anna!
WypiszPowitanie("Anna", "Witaj");           // Witaj, Anna!
WypiszPowitanie("Marek", "Dzień dobry");    // Dzień dobry, Marek!

Praktyczny przykład: Kalkulator ceny

cs/ObliczCene.cs C#
// Rabat domyślnie 0%, VAT domyślnie 23%
static double ObliczCene(double cenaBazowa, double rabat = 0, double vat = 23)
{
    double cenaPoRabacie = cenaBazowa - (cenaBazowa * rabat / 100);
    double cenaZVat = cenaPoRabacie + (cenaPoRabacie * vat / 100);
    return cenaZVat;
}

// Wywołania:
double cena1 = ObliczCene(100);            // 100zł, 0% rabatu, 23% VAT = 123zł
double cena2 = ObliczCene(100, 10);        // 100zł, 10% rabatu, 23% VAT = 110.7zł
double cena3 = ObliczCene(100, 10, 8);    // 100zł, 10% rabatu, 8% VAT = 97.2zł
⚠️ Ważna zasada

Parametry domyślne MUSZĄ być na końcu listy parametrów!

✅ Poprawnie

void F(int a, int b, string c = "x")
Parametr domyślny na końcu

❌ Błąd kompilacji

void F(int a, string c = "x", int b)
Parametr bez domyślnej po parametrze z domyślną

Parametr ref – przekazywanie przez referencję

Normalnie funkcja otrzymuje kopię wartości. Zmiany wewnątrz funkcji nie wpływają na oryginalną zmienną. Słowo ref pozwala funkcji modyfikować oryginalną zmienną.

Bez ref
kopia wartości
Zmiana
tylko kopii
Oryginał
bez zmian
Z ref
adres zmiennej
Zmiana
oryginału
Oryginał
zmieniony!

Przykład: Porównanie z ref i bez ref

cs/RefPorownanie.cs C#
// BEZ ref – zmienia tylko kopię
static void ZwiekszBezRef(int liczba)
{
    liczba++;  // Zmienia KOPIĘ
}

// Z ref – zmienia oryginał
static void ZwiekszZRef(ref int liczba)
{
    liczba++;  // Zmienia ORYGINAŁ
}

// Test:
int a = 5;
ZwiekszBezRef(a);
Console.WriteLine(a);  // 5 – BEZ ZMIAN!

int b = 5;
ZwiekszZRef(ref b);  // UWAGA: "ref" też przy wywołaniu!
Console.WriteLine(b);  // 6 – ZMIENIONE!

Klasyczny przykład: Zamiana wartości

cs/ZamianaRef.cs C#
static void ZamienWartosci(ref int a, ref int b)
{
    int temp = a;
    a = b;
    b = temp;
}

int x = 5, y = 10;
Console.WriteLine($"Przed: x={x}, y={y}");  // x=5, y=10

ZamienWartosci(ref x, ref y);

Console.WriteLine($"Po: x={x}, y={y}");     // x=10, y=5
Pamiętaj o ref przy wywołaniu!

Słowo ref musi być zarówno w definicji funkcji, jak i przy jej wywołaniu. To celowe – programista widzi, że zmienna może zostać zmodyfikowana.

06

Zakres zmiennych (scope)

Zmienne mają ograniczony „zasięg”. Zmienna lokalna istnieje tylko wewnątrz funkcji, w której została utworzona.

cs/ZakresZmiennych.cs C#
class Program
{
    // Zmienna na poziomie klasy – dostępna wszędzie w klasie
    static int liczbaGlobalna = 10;

    static void PrzykladZakresu()
    {
        // Zmienna lokalna – dostępna tylko w tej funkcji
        int liczbaLokalna = 5;

        Console.WriteLine(liczbaGlobalna);  // ✅ OK
        Console.WriteLine(liczbaLokalna);   // ✅ OK
    }

    static void Main()
    {
        Console.WriteLine(liczbaGlobalna);  // ✅ OK
        // Console.WriteLine(liczbaLokalna); // ❌ BŁĄD! Nie istnieje tutaj
    }
}
Zasada: im mniejszy zakres, tym lepiej

Staraj się używać zmiennych lokalnych. Zmienne „globalne” (na poziomie klasy) utrudniają śledzenie, kto i kiedy je modyfikuje.

07

Przeciążanie funkcji (overloading)

Możesz mieć kilka funkcji o tej samej nazwie, ale z różnymi parametrami. Kompilator wybierze właściwą na podstawie argumentów.

cs/Przeciazanie.cs C#
// Ta sama nazwa "Policz", różne parametry:

// Wersja dla dwóch int
static int Policz(int a, int b)
{
    return a + b;
}

// Wersja dla dwóch double
static double Policz(double a, double b)
{
    return a + b;
}

// Wersja dla trzech int
static int Policz(int a, int b, int c)
{
    return a + b + c;
}

// Wywołania – kompilator wybiera właściwą wersję:
int w1 = Policz(5, 3);         // Wersja int, int
double w2 = Policz(5.5, 3.2);  // Wersja double, double
int w3 = Policz(1, 2, 3);      // Wersja int, int, int
Kiedy używać?

Przeciążanie jest przydatne, gdy ta sama operacja logiczna może działać na różnych typach danych. Zamiast DodajInt, DodajDouble, DodajTrzy – masz jedno Dodaj.

Uwaga

Funkcje muszą różnić się parametrami (liczbą lub typami). Nie możesz mieć dwóch funkcji różniących się tylko typem zwracanym!

Zadanie

Zadanie dla uczniów

Kalkulator ocen

Napisz program z następującymi funkcjami:

  • static void WypiszMenu() – wyświetla menu programu
  • static double ObliczSrednia(int o1, int o2, int o3) – oblicza średnią z 3 ocen
  • static string DajOpis(double srednia) – zwraca opis słowny:
    • ≥ 4.5 → „bardzo dobry”
    • ≥ 3.5 → „dobry”
    • ≥ 2.5 → „dostateczny”
    • < 2.5 → „niedostateczny”
  • static void WypiszWynik(string imie, double srednia, string opis) – wyświetla podsumowanie

Przykładowy wynik:

Wynik w konsoli Output
=== KALKULATOR OCEN ===
Podaj imię: Anna
Podaj ocenę 1: 4
Podaj ocenę 2: 5
Podaj ocenę 3: 4
-----------------------
Uczeń: Anna
Średnia: 4.33
Wynik: dobry

⭐ Bonus 1: Dodaj przeciążoną wersję ObliczSrednia dla 4 i 5 ocen

⭐⭐ Bonus 2: Dodaj funkcję z parametrem ref, która zamienia dwie najgorsze oceny miejscami (do wyświetlenia posortowanych)