#import "@preview/ilm:1.4.1": * #import "@preview/codly:1.3.0": * #import "@preview/codly-languages:0.1.1": * #set text(lang: "pl") #let start_date = datetime(year: 2025, month: 9, day: 21) #show: ilm.with( title: [Programowanie], author: "Gabriel Kaszewski", date: start_date, date-format: "[year]", abstract: [ Celem tej książki jest nauczenie czytelnika wspaniałej umiejętności jaką jest programowanie. ], preface: [ #align(center + horizon)[ Książkę dedykuję mojemu Dziadkowi, #linebreak() który wprowadził mnie w świat programowania. ] ], bibliography: bibliography("refs.bib"), figure-index: (enabled: true), table-index: (enabled: true), listing-index: (enabled: true), ) #show: codly-init.with() = Wstęp Witaj w świecie programowania! Cieszę się, drogi czytelniku, że zdecydowałeś się na ten krok. Otworzy on przed Tobą drzwi do fascynującego świata technologii, w którym jedynym ograniczeniem jest wyobraźnia. Mam nadzieję, że ta książka pozwoli Ci zapuścić w tym świecie korzenie i rozwinąć skrzydła. Być może zastanawiasz się, czy jest to książka dla Ciebie. To świetne pytanie! Moim celem jest nauczenie kogokolwiek programowania, niezależnie od wieku, płci, wykształcenia czy doświadczenia. Jeśli potrafisz czytać i pisać, to ten podręcznik jest właśnie dla Ciebie. Nie traćmy więc czasu. Zaparzmy herbatę i zaczynajmy. Chciałbym wyjaśnić Ci zamysł tej książki. Nie skupia się ona na nauce jednego, konkretnego języka, ale na uniwersalnych zasadach, koncepcjach i wzorcach myślenia, które stanowią esencję programowania. Dzięki takiemu podejściu, niezależnie od tego, jaką technologię wybierzesz w przyszłości, będziesz dysponować solidnym fundamentem, który pozwoli Ci błyskawicznie opanować każde nowe narzędzie. Jako język demonstracyjny dla przykładów kodu wybrałem C\# w wersji 12. Nie martw się jednak, jeśli nigdy nie miałeś z nim do czynienia lub pracujesz na innej wersji. Zagadnienia, które poruszam, są na tyle uniwersalne, że z łatwością odnajdziesz je w niemal każdym współczesnym języku programowania. *Ważna uwaga*: Ta książka koncentruje się wyłącznie na sztuce programowania. Celowo pomijam w niej kwestie techniczne, takie jak instalacja i konfiguracja środowiska programistycznego. Zakładam, że poradzisz sobie z tym samodzielnie, korzystając z jednego z wielu doskonałych poradników dostępnych w internecie. Każdy rozdział ma podobną strukturę: najpierw wprowadzę Cię w nowe zagadnienie, następnie zilustruję je praktycznym przykładem kodu, który szczegółowo omówię. Na końcu każdego tematu znajdziesz zestaw ćwiczeń do samodzielnego rozwiązania, które pozwolą Ci utrwalić wiedzę. Odpowiedzi do zadań umieściłem na końcu książki, ale gorąco zachęcam Cię do podejmowania własnych prób i eksperymentowania. To najlepsza droga, by nauczyć się programować. Gotowy na przygodę? Zaczynajmy! = Podstawy programowania W tym rozdziale przedstawię podstawowe koncepty programowania, które są fundamentem dla dalszej nauki. Omówię takie tematy jak zmienne, typy danych, instrukcje sterujące programem, funkcje czy klasy i obiekty. == Pierwszy program Zgodnie z tradycją, pierwszym programem pisanym podczas nauki programowania jest "Hello, World!". Jego celem jest po prostu wyświetlenie tego napisu na ekranie. Zobaczmy, jak wygląda to w języku C\#. === Kod #codly(languages: codly-languages, zebra-fill: none, display-icon: false, display-name: false) ```cs using System; Console.WriteLine("Hello, World!"); ``` === Rezultat Po uruchomieniu powyższego kodu, na ekranie pojawi się tekst: ``` Hello, World! ``` === Wyjaśnienie Zaledwie dwie linijki kodu wystarczyły, aby komputer wykonał nasze polecenie. Niesamowite, prawda? Przeanalizujmy je krok po kroku. 1. `using System;` - Ta linijka to informacja dla programu: "Będziemy korzystać ze standardowego zestawu narzędzi o nazwie System". System to fundamentalna biblioteka w C\#, zawierająca podstawowe funkcjonalności. Dołączając ją, zyskujemy dostęp do wielu gotowych komponentów, w tym do obsługi konsoli. 2. `Console.WriteLine("Hello, World!");` - To jest serce naszego programu. Rozbijmy je na części: - `Console` - to nazwa gotowego *obiektu* (możemy myśleć o nim jak o narzędziu), który reprezentuje konsolę tekstową – czyli nasze okno wyjściowe. - `.WriteLine(...)` - kropka oddziela obiekt od *metody*, czyli czynności, którą chcemy na nim wykonać. `WriteLine` to polecenie "Napisz linię". - `("Hello, World!")` - w nawiasach podajemy *argument*, czyli dane, na których metoda ma operować. W tym przypadku jest to tekst, który ma zostać wyświetlony. Całą tę linię możemy przeczytać jako: "Używając narzędzia `Console`, wykonaj polecenie `WriteLine` z tekstem `Hello, World!`". Co więcej, metoda `WriteLine` automatycznie dodaje na końcu znak nowej linii, dzięki czemu następny tekst pojawiłby się w kolejnym wierszu. Być może brzmi to jeszcze nieco skomplikowanie. Spróbujmy więc posłużyć się prostszą analogią. Wyobraź sobie, że `System` to wielka skrzynka z narzędziami. `Console` to jedno z tych narzędzi (nasz terminal tekstowy). Z kolei `WriteLine()` to konkretna funkcja, którą to narzędzie potrafi wykonać: "wyświetl linię tekstu". Tekst w nawiasie to po prostu treść, którą przekazujemy do wyświetlenia. *Ważna uwaga*: Zwróć uwagę, że linia z poleceniem kończy się średnikiem (;). W C\# (i wielu innych językach) średnik działa jak kropka w zdaniu, sygnalizuje koniec instrukcji. Jego pominięcie jest jednym z najczęstszych błędów popełnianych przez początkujących programistów. == Czym jest program? Kompilacja? Błąd? O co chodzi? Jeśli te pytania pojawiły się w Twojej głowie, to świetnie. Właśnie teraz wszystko sobie wyjaśnimy. Najprościej mówiąc, *program komputerowy to zestaw instrukcji*, które komputer potrafi wykonać. Piszemy je w języku programowania (jak C\#), który jest dla nas zrozumiały. Komputer posługuje się jednak językiem maszynowym, składającym się głównie z zer i jedynek. Proces tłumaczenia naszego kodu na język maszynowy nazywa się *kompilacją*. W jej wyniku powstaje plik wykonywalny, gotowy do uruchomienia program. Bardzo istotne jest, by pamiętać, że instrukcje w programie wykonują się w określonej kolejności, zazwyczaj *od góry do dołu*. Wykonywanie kodu rozpoczyna się w specjalnym miejscu, zwanym *punktem wejścia*. W wielu językach, w tym w C\#, jest nim tradycyjnie funkcja o nazwie `main()`. _Możesz teraz słusznie zauważyć, że w naszym pierwszym programie "Hello, World!" nie było żadnej funkcji `main()`. To dlatego, że nowoczesny C\# dla uproszczenia pozwala ją ukryć w małych programach. Kompilator wciąż tworzy ją dla nas automatycznie "w tle". W bardziej złożonych aplikacjach zobaczymy ją już napisaną jawnie._ Nie wszystkie języki wymagają kompilacji. Niektóre, jak Python czy JavaScript, są *interpretowane*. Oznacza to, że specjalny program zwany interpreterem tłumaczy nasz kod na język maszynowy na bieżąco, w momencie jego uruchamiania. Programy pisane w takich językach wymagają, aby na komputerze użytkownika był zainstalowany odpowiedni interpreter. Warto też wspomnieć, że między kompilacją a uruchomieniem programu zachodzi jeszcze *linkowanie*. To etap, na którym do naszego kodu dołączane są dodatkowe, gotowe biblioteki. W naszym przykładzie `using System;` dało kompilatorowi znać, że będziemy korzystać z biblioteki `System`, a linker zadbał o to, by jej funkcjonalność została poprawnie "połączona" z naszym programem. Jakie to ma dla nas znaczenie w praktyce? Jedną z kluczowych różnic jest sposób wykrywania błędów. W językach kompilowanych (jak C\#) kompilator analizuje cały kod, zanim jeszcze program zostanie uruchomiony. Jeśli znajdzie błędy składniowe (np. literówkę w nazwie polecenia lub brak średnika), przerwie kompilację i nie pozwoli uruchomić programu, dopóki ich nie naprawimy. W językach interpretowanych błędy często wykrywane są dopiero w momencie, gdy interpreter natrafi na problematyczną linię podczas działania programu. Może to oznaczać, że program uruchomi się i będzie działał przez jakiś czas, a następnie nagle przerwie swoje działanie z powodu błędu. Czy to oznacza, że program skompilowany bez błędów zawsze będzie działał poprawnie? Niestety nie. Kompilator jest strażnikiem składni, ale nie rozumie logiki naszego programu. Może on wykryć błąd składniowy, ale nie *błąd logiczny* (np. gdy każemy programowi dodać dwie liczby, a tak naprawdę chcieliśmy je pomnożyć) ani *błąd wykonania* (np. próba dzielenia przez zero). Tego typu problemy wciąż mogą pojawić się podczas działania aplikacji. == Typy danych Wyobraź sobie, że dane w programie przechowujemy w pudełkach. W prawdziwym świecie mamy różne rodzaje pudełek na różne przedmioty – telewizora nie włożymy do pudełka po butach, bo po prostu się nie zmieści. Różne rodzaje danych wymagają różnych "cyfrowych pudełek". W naszym świecie nazywamy je *typami danych.* To właśnie typ określa, jaką wartość można przechować w danym miejscu w pamięci. Decyduje on również o tym, ile miejsca ta wartość zajmie i jakie operacje będzie można na niej wykonywać. Wybór odpowiedniego typu jest kluczowy dla wydajności i poprawności programu. Na początku naszej przygody z programowaniem będziemy korzystać głównie z kilku podstawowych typów: - `int` - do przechowywania liczb całkowitych (np. `10`, `-5`, `2024`). - `double` - do przechowywania liczb ułamkowych (np. `3.14`, `-0.5`). - `string` - do przechowywania tekstu (np. `"Ania"`, `"Hello, World!"`). - `bool` - do przechowywania wartości logicznych (prawda/fałsz, czyli `true`/`false`). Oczywiście, języki programowania oferują znacznie więcej wyspecjalizowanych typów. Poniższa tabela przedstawia podstawowe typy danych dostępne w języku C\#. Traktuj ją jako podręczną ściągawkę, do której zawsze możesz wrócić. #table( columns: (auto, auto, 1fr, auto), inset: 6pt, align: horizon, table.header([Typ danych], [Rozmiar w pamięci], [Zakres wartości], [Przykład wartości]), "byte", "8 bitów", "0 do 255", "200", "sbyte", "8 bitów", "-128 do 127", "-100", "short", "16 bitów", "-32 768 do 32 767", "30000", "ushort", "16 bitów", "0 do 65 535", "60000", "int", "32 bity", [$-2^31$ do $2^31 - 1$], "2000000000", "uint", "32 bity", [0 do $2^32 - 1$], "4000000000", "long", "64 bity", [$-2^63$ do $2^63 - 1$], "9000000", "ulong", "64 bity", [0 do $2^64 - 1$], "18000000000000", "float", "32 bity", [$plus.minus 1.5 times 10^-45$ do $plus.minus 3.4 times 10^38$], "3.14f", "double", "64 bity", [$plus.minus 5.0 times 10^-324$ do $plus.minus 1.7 times 10^308$], "3.14159265358979", "decimal", "128 bitów", [$plus.minus 1.0 times 10^-28$ do $plus.minus 7.9 times 10^28$], "79.99m", "char", "16 bitów", "Pojedynczy znak Unicode", "'A'", "string", "Zmienny", "Ciąg znaków Unicode", `"Hello, World!"`, "bool", "8 bitów", "true lub false", "true", ) W tabeli powyżej przedstawiłem podstawowe typy danych w języku C\#. Oczywiście, istnieją też bardziej zaawansowane typy danych, takie jak tablice, listy, czy klasy, które omówię w dalszej części książki. Warto zauważyć, że typy liczbowe dzielą się na liczby *ze znakiem* i *bez znaku*. Liczby ze znakiem (np. `int`, `long`) mogą przechowywać wartości dodatnie i ujemne. Liczby bez znaku (np. `uint`, `ulong`) przechowują tylko wartości dodatnie, ale dzięki temu mają dwukrotnie większy zakres dodatni. Typ `float` to typ zmiennoprzecinkowy pojedynczej precyzji (dokładność do ok. 7 cyfr), a `double` podwójnej precyzji (dokładność do ok. 15-16 cyfr). Do obliczeń finansowych, gdzie precyzja jest absolutnie krytyczna, używa się typu `decimal`, który eliminuje typowe dla `float` i `double` błędy zaokrągleń. _Ciekawostka: Zwróć uwagę na litery `f` i `m` w przykładach `3.14f` i `79.99m`. W C\# informują one kompilator, że dana liczba ma być traktowana jako `float` lub `decimal`. Domyślnie każda liczba z kropką dziesiętną jest traktowana jako `double`._ Być może zastanawiasz się, dlaczego typ `bool` zajmuje 8 bitów, skoro potrzebuje tylko jednego do przechowania wartości `true` lub `false`. Dzieje się tak, ponieważ najmniejszą jednostką pamięci, do której komputer może się bezpośrednio odwołać, jest bajt (8 bitów). Nawet jeśli realnie potrzebujemy tylko jednego bitu, musimy zarezerwować cały bajt. == Zmienne No dobrze, nasz pierwszy program był bardzo prosty i przez to można by powiedzieć, że nie był zbyt ciekawy, bo przecież programy, do których jesteśmy przyzwyczajeni robią coś więcej niż tylko wyświetlanie tekstu na ekranie. Jedną z podstawowych rzeczy, które pozwalają programom robić coś więcej, są zmienne. Zmienne to są wspomniane przeze mnie juz takie "pudełka", w których możemy przechowywać różne wartości, takie jak liczby, tekst, czy inne dane. Jak sama nazwa wskazuje, wartość przechowywana w zmiennej może się zmieniać w trakcie działania programu. Jest to niesamowicie użyteczna właściwość, ponieważ pozwala programom na dynamiczne reagowanie na różne sytuacje i dane wejściowe. === Przykład Zastosowanie zmiennych w praktyce najlepiej zobrazować na przykładzie. Poniżej znajduje się prosty program, który pyta użytkownika o jego wiek, a następnie wyświetla go na ekranie. #codly(languages: codly-languages, zebra-fill: none, display-icon: false, display-name: false) ```cs using System; int age; Console.WriteLine("Enter your age:"); age = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("You are " + age + " years old."); int nextYearAge = age + 1; Console.WriteLine("Next year, you will be " + nextYearAge + " years old."); ``` === Wyjaśnienie Przyjrzyjmy się, jak działa ten program krok po kroku. 1. `int age;` - Ta linia *deklaruje* zmienną o nazwie `age`, która będzie przechowywać dane typu `int` (liczba całkowita). Deklaracja to jakby zarezerwowanie w pamięci komputera pustego pudełka z etykietą "age". 2. `Console.WriteLine("Enter your age:");` - Ta linia, tak jak w poprzednim programie, wyświetla na ekranie prośbę o podanie wieku. 3. `age = Convert.ToInt32(Console.ReadLine());` - Tutaj dzieje się najwięcej, więc przeanalizujmy to od środka: - `Console.ReadLine()` - ta część czeka, aż użytkownik coś wpisze i naciśnie klawisz `Enter`. Co ważne, niezależnie od tego, co wpiszesz, program zawsze odczyta to jako tekst (`string`). - `Convert.ToInt32(...)` - odczytany tekst jest następnie przekazywany do tej metody. Jej zadaniem jest próba zamiany (konwersji) tekstu na liczbę całkowitą (`int`). Ten proces nazywamy *konwersją typów*. - `age = ...` - na końcu, wynik konwersji (już jako liczba) jest przypisywany do naszej zmiennej `age`. _Co by się stało, gdyby użytkownik wpisał "abc" zamiast liczby? Program zakończyłby działanie błędem. Na razie zakładamy, że dane wejściowe są poprawne. Obsługą nieoczekiwanych sytuacji zajmiemy się w dalszych rozdziałach._ 4. `Console.WriteLine("You are " + age + " years old.");` - Ta linia wyświetla wynik. Znak `+` użyty w ten sposób łączy ze sobą fragmenty tekstu oraz wartość zmiennej `age` w jeden ciąg znaków. Nazywamy to *konkatenacją*. 5. `int nextYearAge = age + 1;` - Deklarujemy nową zmienną `nextYearAge` i od razu przypisujemy jej wartość. Tą wartością jest wynik prostego działania matematycznego: zawartość zmiennej `age` plus `1`. 6. `Console.WriteLine("Next year, you will be " + nextYearAge + " years old.");` - Na koniec, podobnie jak wcześniej, wyświetlamy wiek użytkownika w przyszłym roku, korzystając z nowej zmiennej. === Ćwiczenia 1. Napisz program, który pyta użytkownika o jego imię i wyświetla spersonalizowane powitanie (np. "Witaj, Aniu!"). 2. Napisz program, który prosi użytkownika o podanie dwóch liczb całkowitych, a następnie wyświetla ich sumę. 3. Napisz program, który pyta użytkownika o promień koła (może to być liczba z częścią ułamkową) i na tej podstawie oblicza oraz wyświetla pole jego powierzchni (użyj wzoru: pole = $pi * r^2, "gdzie" pi approx 3.14$). == Instrukcje sterujące programem W tym rozdziale omówię, w jaki sposób jesteśmy w stanie sterować przepływem wykonania naszego programu. W programowaniu mamy dostępne kilka rodzajów instrukcji sterujących. Są to instrukcje warunkowe, czyli wykonaj kod jeśli dany warunek jest spełniony. Instrukcje powtarzające się (pętle), czyli wykonaj dany fragment X razy. Instrukcje skoku, czyli bezpośrednio przejdź do danego miejsca. Z tych ostatnich generalnie nie powinno się korzystać, bo wprowadzają chaos i trudność analizy kodu później. No i na samym końcu mamy hybrydowe zestawienie, które łączy skok z warunkami (switch, match). === Instrukcje warunkowe Jak wspomniałem instrukcje warunkowe pozwalają wykonać kod, gdy pewien warunek jest spełniony. Jest to bardzo użyteczne narzędzie, bez którego programy nie byłyby za ciekawe. ==== Przykład ```cs int age = 20; if (age >= 18) { Console.WriteLine("Gratuluję, jesteś pełnoletni!"); } else { Console.WriteLine("Niestety, jesteś niepełnoletni."); } age = 25; if (age >= 35) { Console.WriteLine("Mozesz byc prezydentem."); } else if (age >= 21) { Console.WriteLine("Mozesz byc posłem."); } else if (age >= 18) { Console.WriteLine("Możesz głosować."); } else { Console.WriteLine("Nie możesz byc prezydentem, posłem ani głosować."); } ``` ==== Rezultat Wynik działania powyższego kodu to: ``` Gratuluję, jesteś pełnoletni! Mozesz byc posłem. ``` ==== Wyjaśnienie Jak widać na przykładzie, podstawowa instrukcja warunkowa ma konstrukcję: ```cs if (warunek) { // Kod do wykonania, jeśli warunek jest prawdziwy } ``` Możemy ją przeczytać jako: "jeśli (`if`) warunek w nawiasach jest prawdziwy, to wykonaj kod zawarty między klamrami". Często chcemy jednak, aby w przypadku niespełnienia warunku wykonał się inny fragment kodu. Do tego służy konstrukcja `else` (w przeciwnym razie): ```cs if (warunek) { // Warunek spełniony, wykonaj ten fragment } else { // W przeciwnym razie, wykonaj to } ``` W naszym przykładzie użyliśmy jeszcze bardziej rozbudowanej formy: łańcucha `else if`. Pozwala on na sprawdzanie wielu warunków po kolei: ```cs if (warunek1) { ... } else if (warunek2) { ... } else if (warunek3) { ... } else { ... } ``` Program sprawdza warunki od góry do dołu. Gdy tylko natrafi na *pierwszy prawdziwy warunek*, wykonuje przypisany do niego blok kodu i *ignoruje wszystkie pozostałe* części tej konstrukcji (`else if` oraz `else`). Jeśli żaden z warunków nie jest prawdziwy, wykonywany jest opcjonalny blok `else` na samym końcu. *Kolejność ma kluczowe znaczenie!* Zwróć uwagę, jak ważna jest kolejność warunków w drugim przykładzie. Gdybyśmy odwrócili logikę i zaczęli od najniższego progu: ```cs // NIEPOPRAWNA KOLEJNOŚĆ - BŁĄD LOGICZNY! if (age >= 18) { Console.WriteLine("Możesz głosować."); } else if (age >= 21) { Console.WriteLine("Możesz być posłem."); } else if (age >= 35) { Console.WriteLine("Możesz być prezydentem."); } ``` Dla osoby w wieku 40 lat program sprawdziłby pierwszy warunek (`40 >= 18`), uznał go za prawdziwy i wyświetlił "Możesz głosować.", po czym zakończyłby sprawdzanie. Nigdy nie dowiedzielibyśmy się, że ta osoba ma również inne prawa. Dlatego warunki w takich łańcuchach zawsze układamy *od najbardziej szczegółowego do najbardziej ogólnego*. W nawiasach przy `if` umieszczamy wyrażenie, które musi dać w wyniku prawdę lub fałsz. Wyrażenie `age >= 18` wykorzystuje operator porównania `>=`. W programowaniu mamy do dyspozycji cały zestaw takich operatorów, bardzo podobnych do tych znanych z matematyki. #table( columns: (auto, auto), inset: 10pt, align: horizon, table.header([Operator], [Znaczenie]), "==", "jest równe", "!=", "nie jest równe", ">", "większe niz", ">=", "większę bądź równe", "<", "mniejsze niż", "<=", "mniejsze bądź równe", "&&", "i", "||", "lub", "!", "nie (negacja)", ) _*Ważna uwaga*: Pamiętaj, aby do *porównywania* wartości zawsze używać podwójnego znaku równości `==`. Pojedynczy znak `=` służy do przypisywania wartości do zmiennych. Pomylenie tych dwóch operatorów to jeden z najczęstszych błędów początkujących._ Wynikiem działania operatora porównania jest zawsze wartość typu `bool` (`true` lub `false`). Możemy to wykorzystać, aby pisać bardziej czytelny kod: ```cs bool isAdult = age >= 18; if (isAdult) { Console.WriteLine("Gratuluję, jesteś pełnoletni!"); } ``` W tym fragmencie najpierw obliczamy warunek i zapisujemy jego wynik ( `true` lub `false`) w zmiennej `isAdult`. Następnie sama zmienna staje się warunkiem w instrukcji `if`. Zauważ, że nie musimy pisać` if (isAdult == true)`, ponieważ zmienna `isAdult` już sama w sobie przechowuje dokładnie taką wartość, jakiej oczekuje instrukcja `if`. Aby sprawdzić, czy jest fałszywa, używamy operatora negacji: `if (!isAdult)`. ==== Ćwiczenia 1. Napisz program, który pyta użytkownika o jego wiek i wyświetla odpowiednią wiadomość w zależności od tego, czy jest on pełnoletni (18 lat lub więcej), nastolatkiem (13-17 lat) czy dzieckiem (12 lat lub mniej). 2. Napisz program, który prosi użytkownika o podanie liczby całkowitej i sprawdza, czy jest ona parzysta czy nieparzysta. 3. Napisz program, który pyta użytkownika o jego ocenę (0-100) i wyświetla odpowiednią wiadomość: "Niedostateczna" (0-59), "Dostateczna" (60-69), "Dobra" (70-79), "Bardzo dobra" (80-89), "Celująca" (90-100). Jeśli ocena jest poza tym zakresem, wyświetl "Nieprawidłowa ocena". === Pętle Następnym rodzajem instrukcji sterujących programem to są instrukcje powtórzeń: *pętle*. Pętle pozwalają nam na wykonanie bloku kodu wiele razy i wraz ze spełnieniem pewnego warunku. W programowaniu wyrózniamy poszczególne rodzaje pętel. Pętla `for` czyli pętla, w której definiujemy *iterator*, czyli zmienna, która będzie zwiększała się o określoną wartość z kazda iteracja pętli (stąd nazwa iteracja), najczęściej zwiększa się o 1. Następnie definiuje się warunek, wraz z którym pętla ma się skończyć. Na końcu instruujemy o ile ma się zwiększyć (bądź zmniejszyć) nasz iterator. Innym rodzajem pętel jest pętla `while`, która potwarza kod, tak długo az podany jej warunek jest spełniony. Siostrzaną pętlą jest pęlta `do while`, która rózni sie tym, ze na pewno wykona sie raz. Jest jeszcze pętla `foreach`, która w róznych jezykach ma rózna składnię, ale koncept ten sam. Polega ona na tym, ze iteruje po elementach zbioru bądź kolekcji. ==== Przykład ```cs Console.WriteLine("Let's count to 10."); for (int i = 0; i < 10; i++;) { Console.WriteLine(i + 1); } bool shouldQuit = false; while (shouldQuit) { Console.WriteLine("I will run until you type 'q'.") char response = Console.ReadLine(); if (response == 'q') { shouldQuit = true; } } string correctPin = "1234"; string enteredPin = ""; do { Console.Write("Please provide your PIN: "); enteredPin = Console.ReadLine(); if (enteredPin != correctPin) { Console.WriteLine("Incorrect PIN. Try again"); } } while (enteredPin != correctPin); Console.WriteLine("Correct PIN! Access granted."); string[] shoppingList = new string[] { "bread", "chicken", "butter"}; Console.WriteLine("Your shopping list:"); foreach (string product in shoppingList) { Console.WriteLine($"- {product}"); } ``` ==== Rezultat ==== Wyjaśnienie ==== Ćwiczenia === Instrukcje skoku ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia == Funkcje === Przykład === Wyjaśnienie === Ćwiczenia == Klasy i obiekty === Przykład === Wyjaśnienie === Ćwiczenia == Dokumentacja kodu === Przykład === Wyjaśnienie == Podsumowanie = Pamięć == Jak działa pamięć komputera == Zarządzanie pamięcią === Manualne zarządzanie pamięcią ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Automatyczne zarządzanie pamięcią (Garbage Collector) ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Inny rodzaj zarządzania pamięcią (Borrow Checker) ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia == Zalety i wady różnych metod zarządzania pamięcią == Podsumowanie = Paradygmaty programowania == Programowanie proceduralne === Przykład === Wyjaśnienie === Ćwiczenia == Programowanie obiektowe === Przykład === Wyjaśnienie === Ćwiczenia == Programowanie funkcyjne === Przykład === Wyjaśnienie === Ćwiczenia = Programowanie obiektowe == Dziedziczenie === Przykład === Wyjaśnienie === Ćwiczenia == Polimorfizm === Przykład === Wyjaśnienie === Ćwiczenia == Enkapsulacja === Przykład === Wyjaśnienie === Ćwiczenia == Abstrakcja === Przykład === Wyjaśnienie === Ćwiczenia = Podstawy alogrytmów i struktur danych == Notacja dużego "O" === Przykład === Wyjaśnienie === Ćwiczenia == Struktury danych === Tablice ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Listy ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Stosy ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Kolejki ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Drzewa ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Grafy ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Krotki ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Słowniki (Mapy) ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia == Algorytmy sortowania === Sortowanie bąbelkowe ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Sortowanie przez wybieranie ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Szybkie sortowanie (Quicksort) ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia == Algorytmy wyszukiwania === Wyszukiwanie liniowe ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia === Wyszukiwanie binarne ==== Przykład ==== Wyjaśnienie ==== Ćwiczenia == Podsumowanie = Programowanie współbieżne == Wątki === Przykład === Wyjaśnienie === Ćwiczenia == Procesy === Przykład === Wyjaśnienie === Ćwiczenia == Asynchroniczność === Przykład === Wyjaśnienie === Ćwiczenia == Synchronizacja === Przykład === Wyjaśnienie === Ćwiczenia == Podsumowanie = Programowanie zdarzeniowe (event-driven programming) === Przykład === Wyjaśnienie === Ćwiczenia = Operacje na plikach === Przykład === Wyjaśnienie === Ćwiczenia = Dobre praktyki programistyczne == Dokumentacja kodu == DRY (Don't Repeat Yourself) == KISS (Keep It Simple, Stupid) == YAGNI (You Aren't Gonna Need It) = Testowanie oprogramowania == Przykład == Wyjaśnienie == Ćwiczenia = Zaawansowane tematy == Wzorce projektowe === Przykład === Wyjaśnienie === Ćwiczenia == Metodyki tworzenia oprogramowania === Przykład === Wyjaśnienie === Ćwiczenia == Refaktoryzacja kodu === Przykład === Wyjaśnienie === Ćwiczenia == Optymalizacja kodu === Przykład === Wyjaśnienie === Ćwiczenia == Kompozycja === Przykład === Wyjaśnienie == Debugowanie = Odpowiedzi do ćwiczeń