Spis treści:
- Dlaczego przetłumaczyliśmy CS50 i jak zorganizowany jest każdy artykuł w kursie
- Pisanie kodu w C i tworzenie kalkulatora
- Styl programowania
- Przepełnienie całkowitoliczbowe
- Wyrażenia warunkowe
- Pętle while
- Pętle for
- Tworzenie funkcji niestandardowych
- Tworzenie gry w C
- Przepełnienie liczby zmiennoprzecinkowej
- Konwersja typu danych
- Więcej o problemach z przepełnieniem
- Wyniki

Darmowy kurs: „Szybki start w Pythonie”
Dowiedz się więcejCS50 (Computer Science 50) to renomowany kurs informatyki z uniwersytetów Harvarda i Yale, uważany za jedno z najlepszych źródeł do nauki podstaw programowania. Doświadczeni programiści polecają ten kurs jako idealne wprowadzenie do programowania. Obejmuje kluczowe tematy, takie jak logika komputerowa, podstawy algorytmów, programowanie w środowisku wizualnym Scratch oraz praca z tablicami i pamięcią. Studenci uczą się struktur danych i podstaw języków programowania, w tym C, Python, SQL, HTML, CSS i JavaScript. Kurs obejmuje również framework Flask i wiele innych ważnych koncepcji, co czyni go wszechstronnym narzędziem dla początkujących i tych, którzy chcą poszerzyć swoją wiedzę z zakresu IT. CS50 to kurs zapewniający dogłębne zrozumienie działania komputerów, obejmujący takie aspekty, jak procesor i pamięć RAM. Pod koniec kursu opanujesz uniwersalne zasady programowania mające zastosowanie w różnych językach, a także nauczysz się interpretować i analizować kod napisany w różnych językach programowania. Ten kurs będzie stanowić podstawę do dalszej edukacji i rozwoju w dziedzinie IT. Opublikowaliśmy kilka artykułów opartych na lekcjach z CS50. Materiały te pomogą Ci lepiej zrozumieć podstawy informatyki i programowania oraz opanować kluczowe koncepcje przedstawione na kursie. Jeśli chcesz pogłębić swoją wiedzę i umiejętności, zalecamy zapoznanie się z naszymi artykułami, które obejmują różnorodne tematy i zadania praktyczne z kursu CS50.
- Podstawy informatyki. Wykład 0.1
- Programowanie w Scratch. Wykład 0.2
- Pierwsze kroki z językiem programowania C. Wykład 1.1
Pierwsze kroki w programowaniu w C. Wykład 1.2. Znajdujesz się w sekcji poświęconej podstawom pisania programów w C. W tym wykładzie omówimy kluczowe koncepcje i składnię języka, które pomogą Ci w tworzeniu pierwszych programów. Po zapoznaniu się z tymi informacjami będziesz mógł śmiało rozpocząć swoją przygodę z programowaniem i tworzeniem oprogramowania w języku C.
Dlaczego przetłumaczyliśmy CS50 i jak zorganizowany jest każdy artykuł w kursie
CS50 to najpopularniejszy kurs na Uniwersytecie Harvarda i jeden z wiodących masowych otwartych kursów online na platformie edX. Wszystkie materiały kursu, w tym ćwiczenia praktyczne, są udostępniane bezpłatnie. Studenci mają możliwość zakupu certyfikatu i dodatkowych korzyści poprzez opłacenie kursu. CS50 obejmuje podstawy informatyki i programowania, co czyni go idealnym wyborem dla początkujących i osób chcących pogłębić swoją wiedzę w tej dziedzinie.
Przekonwertowaliśmy wykłady wideo do formatu tekstowego, dodaliśmy ilustracje i rozszerzyliśmy niektóre wyjaśnienia. Materiały te są teraz dostępne w domenie publicznej. Oryginalny kurs jest licencjonowany na podstawie licencji Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0). Oznacza to, że możesz go modyfikować i rozpowszechniać bezpłatnie, pod warunkiem przestrzegania oryginalnej licencji. Możesz zatem wykorzystywać tę serię materiałów w swojej pracy lub działalności publicznej całkowicie swobodnie i bez dodatkowych kosztów, pod warunkiem przestrzegania warunków licencji.
Każdy artykuł z serii CS50 zawiera następujące materiały:
- tłumaczenie tekstu filmu (czasem połowy filmu, jeśli temat jest obszerny);
- link do oryginalnego filmu w języku angielskim;
- diagramy i wyjaśnienia;
- linki do bardziej szczegółowych materiałów na temat artykułu;
- zadania praktyczne.

Wykłady prowadzi doświadczony nauczyciel o głębokiej wiedzy w swojej dziedzinie. Dzieli się on swoją wiedzą i doświadczeniem, dając studentom możliwość pogłębienia zrozumienia tematu. Każda lekcja jest bogata w przydatne informacje, które przyczyniają się do rozwoju krytycznego myślenia i umiejętności analitycznych u studentów. Uczestnictwo w wykładach pozwoli Ci nie tylko opanować zagadnienia teoretyczne, ale także zastosować je w praktyce. Uczestnicy mają możliwość zadawania pytań i udziału w dyskusjach, co czyni proces nauki interaktywnym i angażującym.
Ten amerykański naukowiec i profesor Uniwersytetu Harvarda jest autorytetem w swojej dziedzinie. Jego badania i publikacje znacząco wpływają na rozwój nauki i edukacji. Ze względu na swój stopień naukowy i doświadczenie, profesor aktywnie uczestniczy w konferencjach międzynarodowych, dzieląc się swoją wiedzą i osiągnięciami. Uniwersytet Harvarda, jako jedna z wiodących instytucji edukacyjnych na świecie, zapewnia platformę wymiany pomysłów i innowacji, co wzmacnia jego reputację w środowisku akademickim.
Ta lekcja obejmuje kluczowe tematy i aspekty, które zostaną omówione szczegółowo. Omówimy kluczowe koncepcje, metody i praktyczne przykłady, aby zapewnić dogłębne zrozumienie materiału. Każdy temat zostanie zilustrowany przykładami ilustracyjnymi, aby utrwalić zdobytą wiedzę. Ta lekcja ma na celu rozwinięcie umiejętności i kompetencji niezbędnych do pomyślnego wykonania zadań w tym obszarze.
- Pisanie kodu w C i tworzenie kalkulatora
- Styl kodu
- Przepełnienie całkowitoliczbowe
- Instrukcje warunkowe
- Pętle while
- Pętle for
- Tworzenie funkcji niestandardowych
- Tworzenie gry w C
- Przepełnienie zmiennoprzecinkowe
- Konwersja typów danych
- Powrót do przepełnienia w praktyce
Pisanie kodu w C i tworzenie kalkulatora
W poprzedniej lekcji omówiliśmy składnię i kluczowe koncepcje języka programowania C. Teraz przejdziemy do ćwiczeń praktycznych i przyjrzymy się, jak pisać programy w tym języku. Otwórz program Visual Studio Code i utwórz plik o nazwie calculator.c za pomocą wiersza poleceń.
Otworzy się on automatycznie w środowisku programistycznym. Zaczniemy od dołączenia bibliotek cs50.h i stdio.h. Biblioteki te udostępniają niezbędne funkcje do pracy z danymi wejściowymi użytkownika i standardowym wejściem/wyjściem, co jest ważnym krokiem w tworzeniu programów w języku C. Dzięki nim będziesz mógł korzystać z funkcji upraszczających przetwarzanie danych i interakcję z użytkownikiem.
Stworzymy prosty kalkulator, używając operatorów poznanych w poprzedniej lekcji. Ten kalkulator umożliwi wykonywanie podstawowych operacji arytmetycznych, takich jak dodawanie, odejmowanie, mnożenie i dzielenie. Skupimy się na stworzeniu intuicyjnego interfejsu i zapewnieniu funkcjonalności, które umożliwią użytkownikom łatwe wykonywanie obliczeń. W miarę rozwoju kalkulatora, poznamy również sposób wykorzystania języka JavaScript do przetwarzania danych wejściowych użytkownika i wyświetlania wyników. W ten sposób nie tylko stworzymy użyteczne narzędzie, ale także utrwalimy naszą wiedzę na temat pracy z operacjami arytmetycznymi w programowaniu.
Aby wykonać operację dodawania, utworzymy zmienne x i y, a następnie wydrukujemy wynik ich sumy, czyli x + y. Jest to podstawowa operacja używana w programowaniu do przetwarzania danych liczbowych. Prawidłowa deklaracja i użycie zmiennych pozwala na efektywne zarządzanie informacjami i wykonywanie różnych obliczeń. W tym przypadku skupimy się na prostym przykładzie pokazującym, jak dodać wartości zmiennych i wydrukować wynik końcowy.
Funkcja printf() w języku programowania C przyjmuje jako pierwszy argument ciąg formatujący, na przykład «%i\n», który określa format wyświetlania danych. Drugim argumentem jest wyrażenie, którego wartość będzie wyświetlana na ekranie. Funkcja ta umożliwia elastyczną kontrolę nad wyprowadzaniem informacji, zapewniając możliwość formatowania liczb, ciągów znaków i innych typów danych. Korzystanie z printf() jest ważnym aspektem tworzenia programów, ponieważ pozwala użytkownikom uzyskać dane w czytelnej formie.
Stworzyliśmy prosty kalkulator, który potrafi dodawać dwie liczby. Po kompilacji program nie generuje żadnych błędów. Uruchommy kalkulator i wykonajmy działanie dodawania 1 + 1.

Wszystko działa poprawnie.
My Wprowadzi zmiany w kodzie kalkulatora, dodając nową zmienną z. Rozszerzy to funkcjonalność naszego kalkulatora i poprawi jego wydajność. Aktualizacja kodu sprawi, że obliczenia będą bardziej elastyczne i wydajne, co zwiększy zadowolenie użytkownika. Prawidłowe użycie zmiennej z pomoże w wykonywaniu bardziej złożonych operacji matematycznych i zapewni dokładniejsze wyniki.
Uruchamiając kalkulator i wykonując działanie 1 + 1, otrzymamy ten sam wynik, który będzie istotny dla wszystkich innych wartości zmiennych x i y. Użycie zmiennej z w kodzie jest uzasadnione w sytuacjach, gdy konieczne jest zapisanie wyniku dodawania do dalszych obliczeń lub ponowne użycie. Takie podejście pozwala ulepszyć strukturę kodu i zwiększyć jego wydajność.
Styl kodu
Rozważmy teraz styl pisania kodu. Nazwy zmiennych x i y są odpowiednie w tym przykładzie, ponieważ są często używane w matematyce. Aby jednak poprawić czytelność kodu, zaleca się używanie bardziej opisowych nazw, takich jak first_number i second_number. Dzięki temu kod będzie bardziej zrozumiały dla innych programistów i uprości się jego późniejsze utrzymanie. Prawidłowe nazewnictwo zmiennych jest ważnym aspektem wysokiej jakości programowania, sprzyjając lepszemu zrozumieniu kodu i ułatwiając jego analizę.
Dodajmy teraz komentarze do programu. Przydadzą się one do przypomnienia sobie funkcjonalności kodu, gdy do niego wrócimy i coś zapomnimy. Linie komentarzy zaczynają się od dwóch ukośników. Komentarze są ważnym elementem programowania, ponieważ ułatwiają zrozumienie kodu zarówno autorowi, jak i innym programistom, którzy mogą pracować z tym kodem w przyszłości. Korzystanie z komentarzy pomaga lepiej ustrukturyzować program i upraszcza proces debugowania.
Komentarze nie wpływają na funkcjonalność programu – służą jedynie wygodzie programistów. W małych projektach ich rola może być nieistotna, ale wraz ze wzrostem rozmiaru kodu komentarze stają się ważne, pomagając w zrozumieniu struktury i logiki programu. Pomagają one zapamiętać, jakie zadanie wykonuje dany fragment kodu, co jest szczególnie ważne podczas pracy w zespole lub po powrocie do projektu po pewnym czasie. Prawidłowe użycie komentarzy poprawia czytelność kodu i ułatwia jego konserwację.
Wskazówka: Większość systemów operacyjnych, w tym Linux, Windows i macOS, obsługuje uzupełnianie kodu. Za pomocą klawisza strzałki w górę można przeglądać historię poleceń i szybko wybierać żądane polecenie, zamiast wielokrotnie wpisywać to samo polecenie. To znacznie poprawia wydajność i oszczędza czas programisty.
Przepełnienie całkowitoliczbowe
Czas teraz na pracę z dużymi liczbami. Rozważmy na przykład liczby x i y równe 1 000 000 000. Wprowadźmy te wartości do wiersza poleceń i przeanalizujmy dane wyjściowe. Praca z dużymi liczbami może być przydatna w różnych obliczeniach i analizie danych, dlatego ważne jest, aby zrozumieć, jak są one obsługiwane w programowaniu i jakie wyniki można uzyskać.

Wszystko poszło zgodnie z oczekiwaniami. Tak planowaliśmy.
Niech zmienne x i y będą równe 2 000 000 000. Wartość ta może być wykorzystywana w różnych obliczeniach i modelach, w których ważna jest wysoka dokładność i szeroki zakres. Na przykład w obliczeniach finansowych, analizie statystycznej lub zadaniach związanych z dużymi zbiorami danych, takie wartości mogą mieć kluczowe znaczenie. Przetwarzanie i analizowanie danych o takich wartościach wymaga stosowania wydajnych algorytmów i zoptymalizowanych podejść w celu uniknięcia błędów i opóźnień w obliczeniach.

Wygląda na to, że wystąpił błąd... Doszło do przepełnienia danych!
Testowanie dodawania dwóch jedynek okazało się zawodne. W ostatnim przykładzie komputerowi zabrakło miejsca na przechowywanie bitów. Problem ten występuje w przypadku różnych typów danych, takich jak string, int, float i char, ponieważ wszystkie one używają ograniczonej liczby bitów do reprezentowania liczb i znaków. Dlatego ważne jest, aby podczas tworzenia oprogramowania uwzględnić ograniczenia typów danych, aby uniknąć błędów i zapewnić stabilność aplikacji.
Liczby całkowite są przechowywane na 32 bitach, co pozwala na reprezentację wartości z zakresu od -2³¹ do 2³¹-1, czyli w przybliżeniu od -2 147 483 648 do 2 147 483 647. Pozwala to na przechowywanie do 4 miliardów liczb całkowitych. Na pierwszy rzut oka może się to wydawać wystarczające do większości zadań. Jednak niektóre aplikacje, takie jak przetwarzanie dużych zbiorów danych lub praca z dużymi liczbami, mogą wymagać większej ilości pamięci. W takich przypadkach warto rozważyć użycie 64-bitowych liczb całkowitych, które zapewniają znacznie szerszy zakres wartości.
Dwa miliardy plus dwa miliardy równa się cztery miliardy. Ta prosta operacja matematyczna demonstruje podstawowe zasady arytmetyki i może być przydatna w wielu dziedzinach, w tym w finansach i ekonomii. Zrozumienie dodawania dużych liczb jest ważne dla analizy danych i podejmowania świadomych decyzji.
Komputery potrafią obsługiwać zarówno liczby dodatnie, jak i ujemne. Oznacza to, że przechowują wartości z zakresu od -2 000 000 000 do 2 000 000 000. Z powodu tego zakresu możemy napotkać nieoczekiwane wyniki podczas wykonywania operacji dodawania.
Aby rozwiązać problem przepełnienia, należy użyć typu danych long. W programie należy zmienić typ zmiennych x i y z int na long, co pozwoli uniknąć ograniczeń związanych z rozmiarem liczb całkowitych. Ta zmiana zapewni prawidłowe działanie programu podczas obsługi dużych wartości i zapobiegnie ewentualnym błędom przepełnienia.
Uruchom kalkulator, aby wykonać niezbędne obliczenia. To narzędzie pozwala szybko i dokładnie wykonywać operacje matematyczne. Za pomocą kalkulatora można łatwo rozwiązywać zadania z arytmetyki, algebry i innych dziedzin matematyki. Stanie się on niezastąpionym pomocnikiem zarówno dla studentów, jak i profesjonalistów, oferując przyjazny interfejs i natychmiastowe wyniki. Upewnij się, że używasz kalkulatora, aby zwiększyć swoją produktywność w nauce lub pracy.

Teraz wszystko zadziałało Wyjdź!
Korzystając z długiego typu danych, wszyscy jesteśmy w równym stopniu ograniczeni skończonymi wartościami liczb. Może to stwarzać problemy podczas projektowania kalkulatora, który musi przetwarzać dowolne dane wejściowe. Z pewnością powrócimy do tego tematu później, aby omówić to bardziej szczegółowo.
Dodanie dwóch liczb, 2 000 000 000 i 2 000 000 000, daje wynik 4 000 000 000. Ten proces demonstruje podstawową operację arytmetyczną — dodawanie, która jest kluczowa dla matematyki. Dodawanie dużych liczb jest ważne w różnych dziedzinach, takich jak ekonomia, finanse i statystyka. Na przykład zrozumienie sumy liczb pozwala lepiej analizować dane i podejmować świadome decyzje. Dodawanie można stosować w budżetowaniu, planowaniu inwestycji i innych zadaniach finansowych.
Instrukcje warunkowe
W tej sekcji przyjrzymy się instrukcjom warunkowym w języku programowania C. Instrukcje warunkowe pozwalają na wykonanie określonych czynności w zależności od prawdziwości lub fałszywości określonego warunku. W języku C instrukcje warunkowe są zapisywane za pomocą operatorów porównania i operatorów logicznych. Podstawowe konstrukcje używane do pracy z warunkami obejmują instrukcję if, instrukcję else i instrukcję switch. Każda z tych instrukcji odgrywa kluczową rolę w kontrolowaniu przepływu programu, umożliwiając programiście implementację logiki podejmowania decyzji. Instrukcje warunkowe stanowią ważną część programowania w języku C i pomagają tworzyć bardziej elastyczne i adaptacyjne aplikacje.
Dodajmy blok else, aby określić, jakie czynności powinny zostać wykonane, jeśli warunek nie zostanie spełniony. Blok else pozwala określić alternatywny scenariusz, co czyni kod bardziej zrozumiałym i uporządkowanym. Poprawia to czytelność i kontrolę logiki programu, umożliwiając programistom łatwe śledzenie możliwych ścieżek wykonywania kodu. Dodanie bloku else zwiększa odporność kodu na błędy i pomaga uniknąć nieoczekiwanych sytuacji podczas wykonywania programu.
Język programowania C charakteryzuje się unikalną składnią. Nawiasy służą zarówno do deklarowania funkcji, jak i do tworzenia wyrażeń logicznych. Ponadto użycie nawiasów klamrowych jest opcjonalne, jeśli zawierają tylko jedną linię kodu z odpowiednim wcięciem. Zdecydowanie jednak zalecam zawsze używanie nawiasów klamrowych, ponieważ znacznie poprawia to czytelność i strukturę kodu. Przejrzysta organizacja kodu sprzyja jego lepszemu postrzeganiu i ułatwia późniejszą konserwację.
Jeśli musisz opisać sytuację, w której x jest równe y, kod będzie wyglądał następująco:
Ostatni warunek można pominąć, ponieważ jeśli pierwsze dwa warunki nie zostaną spełnione, wartość x może być równa wartości y.
Optymalizacja kodu jest ważnym elementem tworzenia aplikacji internetowych. Prawidłowa optymalizacja poprawia wydajność, skraca czas ładowania stron i zwiększa ogólną wydajność witryny. Kluczowe techniki optymalizacji obejmują minifikację kodu HTML, CSS i JavaScript, usuwanie nieużywanego kodu oraz kompresję plików. Buforowanie i optymalizacja obrazów to również ważne czynniki, które należy wziąć pod uwagę, ponieważ przyczyniają się do szybszego ładowania. Czysty i zoptymalizowany kod przynosi korzyści nie tylko użytkownikom, ale także wyszukiwarkom, co wpływa na pozycję witryny w rankingu SEO. Regularne sprawdzanie i aktualizowanie kodu jest niezbędne, aby był aktualny i efektywny. Usuwając trzeci warunek, skracamy czas wykonywania programu, ponieważ nie ma potrzeby sprawdzania tego warunku. Ważne jest, aby pamiętać, że pisząc kod, należy brać pod uwagę nie tylko jego poprawność, ale także wydajność. Optymalizacja kodu może poprawić wydajność programu i zmniejszyć zużycie zasobów, co jest szczególnie ważne podczas tworzenia złożonych systemów. Rozważmy ważne zadanie: ustalenie, ile punktów użytkownik stracił, rozwiązując pierwszy zestaw zadań z kursu CS50. Osobiście straciłem kilka punktów w 1996 roku. Porównajmy teraz wyniki użytkownika z moimi stratami.
Teraz rozumiemy, jak używać wyrażeń warunkowych, ale kod pozostaje zbędny. Zakodowałem na stałe wartość 2 — liczbę utraconych punktów. Jeśli muszę zmienić tę liczbę na 3, jest to proste, ale jeśli liczba punktów jest porównywana w kilku miejscach kodu, na przykład w dwóch, trzech lub pięciu, możemy popełnić błąd podczas ich zastępowania. Dlatego ważne jest, aby unikać kodowania liczb na stałe i używać stałych lub zmiennych, aby poprawić czytelność i łatwość utrzymania kodu. Takie podejście uprości zmiany i zminimalizuje ryzyko błędów.
Aby uprościć pracę z liczbami w programie, zaleca się utworzenie zmiennej na samym początku, która będzie przechowywać tę wartość. Aby uniknąć przypadkowej zmiany tej zmiennej podczas wykonywania kodu, deklarujemy ją jako stałą. Stała informuje kompilator, że wartości tej zmiennej nie można zmienić w przyszłości. To rozwiązanie promuje lepszą organizację kodu i zapobiega potencjalnym błędom związanym ze zmianą wartości.
W językach programowania takich jak C obowiązuje ważna zasada: nazwy stałych powinny być pisane wielkimi literami. Zasada ta poprawia czytelność kodu i pomaga programistom szybko identyfikować wartości stałych. Używanie wielkich liter dla stałych jest powszechną praktyką, która również sprzyja spójności kodu. Przestrzeganie tej zasady sprawia, że kod jest bardziej zrozumiały i łatwiejszy w utrzymaniu.
Stwórzmy program sprawdzający, czy liczba wprowadzona przez użytkownika jest parzysta, czy nieparzysta. Wykorzystamy składnię i metody, które już opanowaliśmy. Ten program pomoże użytkownikom określić, do której kategorii należy wprowadzona liczba, co jest przydatnym zadaniem w programowaniu.
Zgodnie z definicjami matematycznymi liczba jest uważana za parzystą, jeśli po podzieleniu przez dwa reszta wynosi zero. Liczba nieparzysta z kolei daje resztę jeden po podzieleniu przez dwa. Aby obliczyć resztę z dzielenia, można użyć operatora %. Operator ten pozwala określić resztę, jaka pozostaje po podzieleniu jednej liczby przez drugą. Na przykład, używając operatora % z liczbą i dzielnikiem dwóch, można łatwo określić, czy liczba jest parzysta, czy nieparzysta.
W języku programowania C znak «==» oznacza równość, podczas gdy znak «=» służy do przypisywania wartości. To rozróżnienie może wydawać się nietypowe, ale jest ono stosowane od dawna i programiści muszą o tym pamiętać podczas pisania kodu. Inne języki, takie jak JavaScript, używają operatora «===» do ścisłego porównania, o czym również warto pamiętać podczas przełączania się między językami programowania. Zrozumienie tych różnic pomoże uniknąć błędów i poprawić jakość kodu.
Teraz opracujmy program, który prosi użytkownika o zgodę z pewnym stwierdzeniem. Użytkownik musi odpowiedzieć pojedynczym znakiem, na przykład ‘y’ na «tak» lub ‘n’ zamiast «nie». Wszystkie pozostałe znaki zostaną zignorowane.
Program wygląda następująco:
Jeśli użytkownik wybierze odpowiedź T lub N, musimy to uwzględnić w kodzie, dodając logiczne LUB. W języku C dwie pionowe kreski || oznaczają logiczne LUB. W ten sposób będziemy mogli obsłużyć obie opcje odpowiedzi, co uczyni program bardziej elastycznym i odpornym na dane wprowadzane przez użytkownika. Pozwoli to programowi poprawnie reagować na różne opcje odpowiedzi i poprawi komfort użytkowania.
Istnieje alternatywa dla tego rozwiązania: konwersja znaków wejściowych na małe litery może wyeliminować potrzebę używania znaków takich jak ||. To podejście zostanie omówione w przyszłych wykładach.
W tym przykładzie używamy pojedynczych cudzysłowów do oznaczenia znaków, ponieważ pracujemy z typem danych char. Różni się to od pracy z ciągami znaków, które są oznaczane podwójnymi cudzysłowami i są typu string. Należy pamiętać, że zmienne typu char przechowują tylko pojedynczy znak, podczas gdy ciągi znaków mogą zawierać sekwencje znaków. Prawidłowe użycie cudzysłowów ma kluczowe znaczenie dla poprawnego działania programu i jego logiki.
Pętle while
W tej sekcji przyjrzymy się, jak organizować pętle w języku C. Przypomnijmy, że w poprzedniej lekcji nauczyliśmy się, jak sprawić, by kot miauczał. Teraz stworzymy program demonstrujący użycie pętli w C. Pętle pozwalają na powtarzanie pewnych czynności, co czyni kod bardziej wydajnym i zrozumiałym. Przejdźmy do napisania programu, który używa pętli do rozwiązania problemu.
Powyższy tekst zawiera powtarzające się elementy, które należy wyeliminować. W tym celu możemy użyć pętli. Jednym z najłatwiejszych sposobów implementacji tego jest użycie pętli, co przyczynia się do bardziej wydajnego i ustrukturyzowanego kodu. Pętle pozwalają na bardziej zwarte przetwarzanie danych, unikając duplikacji i poprawiając czytelność. Optymalizacja kodu za pomocą pętli nie tylko upraszcza logikę, ale także poprawia wydajność programu.
Wyrażenie logiczne definiujące warunek wykonania pętli jest podane w nawiasach. Pętla będzie wykonywana tak długo, jak długo ten warunek jest spełniony; gdy tylko stanie się fałszywy, wykonywanie pętli zostanie przerwane. Jeśli chcesz, aby pętla działała w nieskończoność, możesz użyć warunku zawsze prawdziwego, na przykład (1 == 1) lub (2 > 1). W języku programowania C stałe logiczne true i false służą do oznaczania wartości true i false.
Aby zapewnić poprawne działanie pętli, ważne jest wprowadzenie licznika. W C i wielu innych językach programowania często używa się zmiennej i jako licznika, zaczynając od wartości początkowej 0. Taka konwencja sprzyja lepszemu zrozumieniu kodu i ułatwia jego czytanie.
Mamy możliwość ulepszenia tego programu, stosując tzw. „cukier składniowy”. Dzięki temu kod będzie bardziej czytelny i łatwiejszy w obsłudze, co z kolei zwiększy produktywność programistów. Uproszczenia składniowe nie dodają nowej funkcjonalności, ale znacznie upraszczają proces pisania i rozumienia kodu. Wdrożenie takich usprawnień może prowadzić do efektywniejszego wykorzystania zasobów i skrócenia czasu programowania.
Wyrażenie i = i + 1 zostało zastąpione wyrażeniem i = i++. Takie zmiany nie wpływają na funkcjonalność programu, ale pozwalają na skrócenie i zwiększenie zwartości kodu. Należy pamiętać, że stosowanie skrótów może poprawić czytelność kodu, ale wymaga starannego rozważenia, aby uniknąć potencjalnych błędów związanych ze specyfiką operatora inkrementacji.
W tej sekcji szczegółowo omówimy algorytm programu. Algorytm to sekwencja kroków wykonywanych przez program w celu osiągnięcia danego celu. Każdy etap algorytmu odgrywa ważną rolę w całym procesie i wpływa na wynik końcowy. Przeanalizujemy kluczowe elementy algorytmu, ich wzajemne powiązania oraz optymalne metody implementacji. Zrozumienie algorytmu pomoże użytkownikom efektywniej korzystać z programu i rozwiązywać problemy.
- Zaczynamy od zainicjowania zmiennej i.
- Następnie komputer sprawdza warunek i < 3. Jeśli jest prawdziwy, wszystko, co znajduje się wewnątrz nawiasów klamrowych, jest wykonywane, a mianowicie program wyświetla meow.
- Wartość i jest zwiększana o jeden.
- Teraz komputer ponownie sprawdza warunek, aby upewnić się, że i nie stało się większe niż 3. Jeśli nie, wykonuje wszystko, co znajduje się wewnątrz bloku.
- Po trzech powtórzeniach warunek stanie się fałszywy, a wykonywanie pętli zakończy się.
- Komputer przechodzi do poleceń następujących po pętli.
Możesz rozpocząć pętlę nie od 0, ale na przykład od 1. W takim przypadku, aby ciało pętli zostało wykonane trzy razy, musisz zmienić warunek pętli. Pozwoli Ci to kontrolować liczbę iteracji i dostosować logikę wykonywania do swoich wymagań. Prawidłowe ustawienie wartości początkowej i warunku pętli to ważny aspekt programowania, który wpływa na wydajność i poprawność kodu.
Zwróć uwagę na poprawną pisownię znaku „mniejszego lub równego”: znak „mniejszego” występuje jako pierwszy, a następnie znak „równego”, bez spacji między nimi. Prawidłowa reprezentacja tego symbolu wygląda następująco: <=.
Możesz ustawić zmienną „i” na 2, 10 lub dowolną inną liczbę, zmieniając warunek. Jednak lepiej jest postępować zgodnie z podstawowymi zasadami i zacząć od zera, stopniowo zwiększając licznik, aż do osiągnięcia pożądanej wartości. Takie podejście zapewnia lepszą czytelność i zrozumienie kodu.
Jeśli planujesz odliczać, zacznij od ustawienia „i” na 3. Zmniejszaj tę wartość, aż osiągnie 0. Takie podejście pomoże Ci efektywnie zorganizować proces liczenia i śledzić postęp.
Aby rozwiązać ten problem, możesz użyć pętli „for”. To narzędzie pozwala na efektywne powtarzanie określonych czynności, co czyni je idealnym rozwiązaniem dla zadań wymagających iteracji. Korzystanie z pętli „for” upraszcza przetwarzanie danych i optymalizuje kod, zapewniając jego przejrzystość i czytelność.
Pętle „for”
Pętla „for” jest szeroko stosowana w języku C i innych językach programowania. Dzięki niej możemy efektywniej organizować nasz kod. Przykład użycia pętli for może wyglądać następująco:
Rozważmy zawartość ujętą w nawiasy.
- Najpierw inicjalizujemy licznik: i = 0.
- Następnie inicjalizowany jest warunek, który będzie sprawdzany za każdym razem, gdy przejdziemy pętlę. Sprawdzamy, czy i jest mniejsze od 3.
- Na koniec zwiększamy licznik o 1.
Pętle for i while wykonują podobne funkcje, ale mają swoje własne osobliwości. W pętli for zmienna i jest deklarowana w nawiasach, co ogranicza jej zakres tylko do tej pętli. Oznacza to, że po zakończeniu pętli zmienna i nie będzie już dostępna. Natomiast w pętli while zmienna i jest deklarowana poza nawiasami, co pozwala jej zachować swoją wartość nawet po zakończeniu pętli. Zrozumienie tych różnic jest ważne dla prawidłowego zarządzania zmiennymi i ich zakresem w kodzie.
Tworzenie funkcji niestandardowych
Utwórzmy własną funkcję w C, którą nazwiemy meow(). Po dodaniu tej funkcji nasz program będzie wyglądał następująco:
Polecenie void meow(void) określa, że funkcja nie przyjmuje żadnych parametrów wejściowych i nie zwraca żadnych wartości. Głównym celem tej funkcji jest wyświetlanie liczb i ciągów znaków na ekranie. Korzystanie z tej funkcji może być przydatne do wyświetlania informacji użytkownikowi lub do debugowania kodu, co czyni ją ważnym narzędziem w programowaniu.
W języku programowania C deklaracja funkcji musi znajdować się na początku programu. Różni się to od innych języków, takich jak Python, gdzie funkcje można umieszczać w dowolnym miejscu kodu. Poprawna organizacja kodu w C pomaga uczynić go zrozumiałym i uporządkowanym, co ułatwia debugowanie i dalszy rozwój.
W ciele pętli for dodaliśmy wywołanie funkcji meow(). Teraz zmieńmy ją tak, aby miauczała wielokrotnie. Aby to zrobić, przeniesiemy pętlę for do funkcji i przekażemy liczbę miauczeń przez argument n. Ponieważ n będzie liczbą całkowitą, musimy określić, że jego typem jest int.
Argument n został dodany do deklaracji funkcji meow() zamiast pustej wartości. Ta zmiana pozwala funkcji zaakceptować wartość, co rozszerza jej możliwości i czyni kod bardziej wszechstronnym. Teraz funkcja meow() może wykorzystać przekazany argument do wykonywania różnych zadań, co zwiększa jej funkcjonalność i możliwości adaptacyjne w różnych scenariuszach użycia.
Utwórzmy funkcję, która będzie akceptować argumenty i zwracać wartość. Jest to dość proste do zaimplementowania w języku C. Funkcja może mieć różne typy wartości zwracanych, co czyni ją uniwersalnym narzędziem do przetwarzania danych. Najpierw zdefiniujemy prototyp funkcji, określając typ zwracany i typy parametrów. Następnie zaimplementujemy funkcję, która wykona niezbędne obliczenia i zwróci wynik. Pozwala to na tworzenie bardziej złożonych i wielokrotnego użytku wywołań funkcji, co poprawia czytelność i łatwość obsługi kodu.
Utwórzmy program, który obliczy cenę produktu z uwzględnieniem rabatu. Program weźmie pierwotną cenę produktu i kwotę rabatu, a następnie obliczy cenę końcową z uwzględnieniem rabatu. Takie podejście pomoże użytkownikom łatwo określić, ile zaoszczędzą na zakupie.
Oto informacje o cenie: „regularna” to regularna cena produktu, a „promocja” to aktualnie obowiązująca cena po rabacie.
Utwórzmy niestandardową funkcję, która pobierze pierwotną cenę i zwróci cenę po rabacie. Ta funkcja ułatwi obliczenie ostatecznej ceny produktu po zastosowaniu rabatu, co jest wygodne dla sklepów internetowych i serwisów oferujących zniżki na swoje produkty. Optymalizacja ofert cenowych za pomocą tej funkcji pomoże poprawić doświadczenia użytkownika i zwiększyć konkurencyjność firmy.
Przekonwertowaliśmy wszystkie zmienne na liczby zmiennoprzecinkowe. Pozwala to na większą dokładność obliczeń i usprawnienie przetwarzania danych w naszym projekcie. Użycie liczb zmiennoprzecinkowych zapewnia bardziej elastyczne zarządzanie wartościami liczbowymi i pozwala uniknąć błędów związanych z dzieleniem całkowitym.
Funkcja discount() nie wyświetla obliczonej wartości na ekranie, lecz przekazuje ją z powrotem do funkcji wywołującej. W tym celu używane jest słowo kluczowe return. Pozwala to na wykorzystanie wartości zwróconej do dalszych obliczeń lub wyświetlenia w programie.
Funkcje mogą przyjmować wiele argumentów, w tym dwa, trzy lub więcej. Rozważmy funkcję discount(), która przyjmuje kwotę rabatu jako argument. Pozwala to na ustawienie dowolnej kwoty rabatu, zamiast ograniczenia do 15%. Korzystanie z różnych wartości rabatów sprawia, że funkcja jest bardziej elastyczna i wszechstronna w różnych scenariuszach zastosowań.
Nasza funkcja z powodzeniem oblicza cenę produktu z uwzględnieniem rabatu, który możesz ustawić samodzielnie. Pozwala to na łatwe dostosowanie ceny do aktualnych ofert i promocji. Skorzystaj z naszej funkcji, aby obliczyć dokładną cenę z dostosowanymi rabatami.
Tworzenie gry w C
Teraz zastosujmy naszą wiedzę do stworzenia małej gry. Pomyślmy o Super Mario Bros.: monety były ukryte za znakami zapytania na niebie, które gracz mógł zbierać. Ten element rozgrywki dodaje emocji i zachęca do eksploracji lokacji w grze. Wykorzystując takie mechanizmy, możemy tworzyć unikalne poziomy, w których gracze muszą znajdować ukryte przedmioty i zdobywać za to bonusy.

Na tym etapie nie możemy stworzyć tętniącego życiem i bogatego świata gry. Zamiast tego, po prostu wstawmy kilka znaków zapytania, aby odzwierciedlić niepewność i oczekiwanie.
Ulepszanie programu za pomocą pętli for
Pętle for to potężne narzędzie do optymalizacji kodu programu. Pozwalają one na efektywne powtarzanie określonych czynności, co jest szczególnie przydatne podczas pracy z tablicami i zbiorami danych. Używając pętli for, można znacznie zmniejszyć liczbę wierszy kodu i poprawić jego czytelność. Użycie pętli for w programie nie tylko upraszcza logikę, ale także poprawia wydajność, umożliwiając wykonywanie wielu operacji w minimalnym czasie.
Używaj pętli for, aby zautomatyzować rutynowe zadania, takie jak przetwarzanie danych, wykonywanie obliczeń czy generowanie raportów. Pozwoli Ci to skupić się na ważniejszych aspektach rozwoju, przyspieszając proces pisania i debugowania kodu. Implementacja pętli for w programie to krok w kierunku bardziej wydajnego i zorganizowanego kodu.
Po zakończeniu pętli for wydrukowaliśmy znak nowej linii \n. Nie można go używać wewnątrz pętli, ponieważ każdy znak zapytania byłby wyświetlany w osobnym wierszu. To ograniczenie należy uwzględnić podczas pracy z formatowaniem danych wyjściowych w pętlach, aby zachować pożądany wygląd informacji.
Skomplikujmy nasz program, dodając możliwość wyświetlania użytkownikowi pytania o liczbę znaków zapytania, które mają zostać wyświetlone na ekranie. W tym celu zapoznamy się z pętlą do while. Pętla ta jest podobna do pętli while, ale różni się tym, że warunek jest sprawdzany po wykonaniu ciała pętli, a nie przed nim. Gwarantuje to, że ciało pętli zostanie wykonane co najmniej raz, co może być przydatne w pewnych sytuacjach programistycznych.
Pętla do while to wygodne narzędzie programistyczne, gdy określone czynności muszą zostać wykonane co najmniej raz, niezależnie od warunku. Główną cechą tej pętli jest to, że warunek jest sprawdzany po wykonaniu bloku kodu, co gwarantuje jego wykonanie, nawet jeśli początkowo okaże się fałszywy. To sprawia, że pętla do while jest szczególnie użyteczna w sytuacjach, gdy na przykład trzeba monitować użytkownika o wprowadzenie danych, aż do wprowadzenia prawidłowej wartości. Użycie pętli do while pozwala efektywnie zarządzać przepływem wykonywania programu, zapewniając elastyczność i kontrolę nad logiką procesu.
Użytkownik raczej nie wprowadzi wartości n = 0 lub n = -100, ponieważ nie mają one logicznego znaczenia. Gdy wartość n stanie się większa lub równa 1, program zakończy bieżącą pętlę, a sterowanie przejdzie do następnego polecenia. Zapewnia to efektywne wykonanie algorytmu i minimalizuje prawdopodobieństwo wystąpienia błędów podczas działania.
W tej części gry Mario schodzi do lochu, gdzie napotyka ścianę z cegieł. Ściana ta jest ważnym elementem rozgrywki, ponieważ gracz musi znaleźć sposób na jej zniszczenie. Aby to osiągnąć, Mario może wykorzystać swoje umiejętności i zdolności, takie jak skakanie czy specjalne power-upy, które pomagają pokonywać przeszkody. Lochy w grze oferują unikalne wyzwania i łamigłówki, dzięki czemu gra jest jeszcze ciekawsza i bardziej ekscytująca. Ważne jest, aby eksplorować otoczenie i odkrywać różne sposoby interakcji z obiektami, takimi jak ceglane ściany, co otwiera nowe możliwości awansowania.

Stwórzmy kwadratowy fragment podobny do tego pokazanego na obrazku. Ponieważ ten kwadrat przedstawia cegły, użyjemy symbolu # do jego wyrenderowania.
Aby ułożyć cegły w wielu rzędach, należy użyć pętli zagnieżdżonej. Przykładowy program demonstruje to podejście.
Pierwsza pętla służy do zliczania wierszy od góry do dołu, podczas gdy druga sekwencyjnie wyświetla znaki każdego wiersza na ekranie, symulując pracę starej maszyny do pisania. To podejście pozwala uzyskać efekt stopniowo pojawiającego się tekstu, co może poprawić komfort użytkowania i uczynić interakcję z treścią bardziej angażującą.
Uruchom program i sprawdź wyniki. Oto, co otrzymaliśmy:

Kwadrat nie jest idealny, ponieważ symbol # jest krótszy niż jego szerokość. Wynika to ze specyfiki użytej czcionki. Niemniej jednak możemy uznać problem za rozwiązany.
Przepełnienie zmiennoprzecinkowe
Wróćmy do naszego kalkulatora i rozważmy problem przepełnienia podczas pracy z dużymi liczbami. Tym razem skupimy się na liczbach zmiennoprzecinkowych. W tym celu zmienimy typ zmiennej z całkowitych (int) na zmiennoprzecinkowe (float) i użyjemy dzielenia zamiast dodawania. Pozwoli nam to wydajniej obsługiwać duże wartości i uniknąć potencjalnych błędów związanych z przepełnieniem. Użycie liczb zmiennoprzecinkowych otwiera nowe możliwości precyzyjnych obliczeń i rozszerza funkcjonalność naszego kalkulatora.
Do kodu dodamy nową zmienną, float z, która będzie równa wynikowi dzielenia x przez y i wyświetli jej wartość na ekranie. Pozwoli nam to zobaczyć wynik operacji i lepiej zrozumieć, jak zmienne są używane w programowaniu.
Uruchommy kalkulator, ustawiając wartości x = 2 i y = 3. To proste obliczenie pozwoli nam wykonać różne działania matematyczne, takie jak dodawanie, odejmowanie, mnożenie i dzielenie. Używając tych wartości, możemy uzyskać wyniki dla następujących wyrażeń: x + y, x - y, x * y i x / y. Operacje te stanowią podstawę zrozumienia bardziej złożonych pojęć matematycznych i pozwalają na skuteczniejsze rozwiązywanie problemów.

Otrzymaliśmy odpowiedź w postaci liczby z sześcioma miejscami po przecinku. Komputer domyślnie zwraca wynik z taką precyzją.
Aby zmniejszyć liczbę miejsc po przecinku do dwóch, należy zmienić format wyjściowy w ostatnim poleceniu. Pozwoli to uzyskać pożądany wynik i poprawić czytelność prezentowanych danych. Prawidłowe formatowanie liczb jest ważne dla zapewnienia dokładności i przejrzystości informacji.
Uruchommy program i rozpocznijmy proces. Program został zaprojektowany do wykonywania określonych zadań, co pozwala zoptymalizować przepływ pracy i zwiększyć wydajność. Upewnij się, że wszystkie niezbędne komponenty są zainstalowane i działają poprawnie. Po uruchomieniu będziesz mógł korzystać ze wszystkich funkcji oferowanych przez to oprogramowanie. Dostosuj ustawienia do swoich potrzeb, aby uzyskać najlepsze rezultaty.

Teraz wyodrębnimy 50 znaków po kropce.
Uruchom kalkulator. To narzędzie pomoże Ci szybko i dokładnie obliczyć niezbędne parametry. Użyj kalkulatora, aby uzyskać aktualne dane, które ułatwią Ci podejmowanie decyzji. Zwróć uwagę na przyjazny dla użytkownika interfejs i łatwość obsługi, dzięki którym proces obliczeń jest szybki i wydajny. Użyj kalkulatora do różnych obliczeń, aby zoptymalizować swój czas i wysiłki.

Nie tylko mamy trudności z dodawaniem miliardów, ale także Nie można również uzyskać dokładnego wyniku dzielenia dwóch liczb. Ten problem uwypukla ograniczenia, z którymi borykają się nie tylko zwykli ludzie, ale także współczesne systemy komputerowe. Ważne jest, aby zrozumieć, że dokładność operacji matematycznych może zależeć od wielu czynników, w tym od zastosowanych algorytmów i reprezentacji liczb.
Występuje zjawisko podobne do przepełnienia przy dodawaniu — program zwraca niepoprawny wynik, jeśli liczba bitów użytych do zapisania liczby całkowitej przekracza określone granice. Nie jest to zaskakujące, ponieważ zbiór liczb całkowitych jest nieskończony, a ich długość nie ma ustalonych granic. Przepełnienie całkowitoliczbowe jest częstym problemem w programowaniu, który może prowadzić do błędów i nieprawidłowego działania aplikacji. Dlatego ważne jest, aby być świadomym ograniczeń podczas pracy z liczbami całkowitymi i stosować metody zapobiegające takim sytuacjom.
W tym przypadku mówimy o liczbach zmiennoprzecinkowych. Zbiór liczb rzeczywistych jest nieprzeliczalny, a długość tych liczb może być nieskończona. Ograniczona pamięć komputera utrudnia pracę z takimi liczbami. Jednak w środowisku naukowym istnieją metody i algorytmy, które mogą poprawić dokładność obliczeń i efektywnie pracować z liczbami zmiennoprzecinkowymi. Rozwiązania te obejmują różne podejścia do reprezentacji liczb i optymalizacji procesów obliczeniowych, co czyni je niezbędnymi w badaniach naukowych i obliczeniach inżynierskich.
Konwersja typów danych
Podczas wykonywania programu komputer może zmienić typ przetwarzanych danych. Rozważmy zmienne x i y zdefiniowane jako liczby całkowite, podczas gdy zmienna z będzie reprezentowana jako liczba zmiennoprzecinkowa. Pozwala to na efektywne zarządzanie różnymi typami danych i ich wykorzystaniem w obliczeniach, zapewniając elastyczność i precyzję przetwarzania informacji.
Uruchom program z podanymi wartościami zmiennych. Ustawmy x na 2, a y na 3.

Wynik był nieoczekiwany. W rzeczywistości wartością oczekiwaną jest ułamek dziesiętny nieskończony równy 0,6666666666 itd. Jednak w języku programowania C, gdy dzielona jest liczba całkowita przez liczbę całkowitą, wynik również jest liczbą całkowitą. Oznacza to, że część ułamkowa mniejsza od 1 jest odrzucana. Ten proces nazywa się obcinaniem i powoduje, że wynik wynosi 0, gdy dzielna jest mniejsza od dzielnika.
Rozważmy następujący przykład. Niech x = 4, a y = 3. Gdy dzielona jest liczba 4 przez 3, wynikiem jest ułamek dziesiętny nieskończony równy 1,33333 itd. Teraz uruchommy kalkulator i wykonajmy to dzielenie.

Komputer podzielił 4 przez 3 za pomocą liczby całkowitej dzielenie, a w rezultacie wynik wyniósł 1,0000. Część ułamkowa liczby została obcięta, co jest typowe dla operacji na liczbach całkowitych.
Aby rozwiązać ten problem, wykorzystaliśmy technikę znaną w C i innych językach programowania jako konwersja typu. Pozwala nam to poprawnie zmienić typ danych, zapewniając poprawną interpretację wartości i minimalizując błędy. Konwersja typu odgrywa kluczową rolę w programowaniu, umożliwiając programistom pracę z różnymi formatami danych i zapewniając ich zgodność. Ważne jest, aby mądrze stosować konwersję typu, aby uniknąć utraty informacji i zapewnić stabilność oprogramowania.
W tej sekcji poinstruujemy komputer, aby traktował zmienne int jako liczby zmiennoprzecinkowe. Teraz uruchommy nasz kalkulator i ponownie podzielmy 2 przez 3.

Wynik staje się dokładniejszy, ale błąd nadal jest angielski: teraźniejszość.
Więcej o problemach z przepełnieniem
Na pierwszym wykładzie przyjrzeliśmy się trzem bitom, które pozwalają nam reprezentować liczby od 0 do 7, co odpowiada kodowi binarnemu od 000 do 111. Następnie zadałem pytanie, jak możemy wyrazić liczbę 8. Jeden ze studentów zasugerował dodanie czwartego bitu. To rzeczywiście jest poprawne, ponieważ dzięki czwartemu bitowi liczbę 8 można przedstawić binarnie jako 1000.
Jeśli nie masz możliwości dodania czwartego bitu, dodanie 1 do liczby 111 daje 000. To zjawisko nazywa się przepełnieniem. W tej sytuacji liczby 8 nie można przedstawić na trzech bitach, a wynikiem operacji jest uzupełnienie zerami. Przepełnienie jest ważnym pojęciem w programowaniu i logice cyfrowej, ponieważ wpływa na obliczenia i reprezentację danych w systemach skończonych.
Problem, o którym mowa, może wydawać się nietypowy, ale wielu spotkało się z nim już wcześniej. Jednym z godnych uwagi przykładów jest problem Y2K. 1 stycznia 2000 roku komputery musiały zaktualizować swoje zegary. Wiele systemów, zwłaszcza tych zaprojektowanych wiele lat temu, zapisywało w datach tylko dwie ostatnie cyfry roku, aby zaoszczędzić pamięć. W związku z tym rok 2000 wyświetlał tylko 00. Jeśli program dodałby prefiks do takiej daty cyfrą 19, system cofnąłby się do roku 1900 zamiast do roku 2000. Ten problem podkreśla znaczenie dobrych praktyk programistycznych i aktualizowania starszych systemów, aby uniknąć podobnych błędów w przyszłości.
Na szczęście do tego czasu znaczna część kodu została poprawiona, co w dużej mierze rozwiązało problem. Istnieje jednak możliwość, że błąd ten powtórzy się 19 stycznia 2038 r. Niektóre systemy oprogramowania reprezentują czas jako liczbę sekund od północy 1 stycznia 1970 r. Jednak starsze systemy używają 32-bitowej liczby całkowitej ze znakiem do przechowywania sekund. Najdłuższa możliwa data, jaką może reprezentować ten format, to 03:14:07, 19 stycznia 2038 r. Dlatego ważne jest, aby uwzględnić tę datę podczas tworzenia i aktualizacji oprogramowania, aby uniknąć podobnych problemów w przyszłości.
Po określonej dacie pole danych może przyjąć wartość ujemną. Liczby ujemne mogą być interpretowane przez programy jako data z 1901 r. Oznacza to, że wszelkie obliczenia oparte na dacie późniejszej niż 19 stycznia 2038 r. mogą dawać nieprawidłowe wyniki.
Obecnie koszt sprzętu znacznie spadł w porównaniu z kilkoma dekadami temu, a wydajność komputerów wzrosła. Dzięki temu ograniczenia sprzętowe nie są już tak istotne dla użytkowników.
Błąd ten może również wystąpić w popularnych aplikacjach. Przyjrzyjmy się przykładowi małego programu, który konwertuje dolary na centy.
Uruchommy program i wprowadźmy kilka wartości zmiennej "kwota". Pozwoli nam to przetestować funkcjonalność i upewnić się, że algorytm działa poprawnie. Zmieniając wartość zmiennej "kwota", możemy obserwować, jak program reaguje na różne dane wejściowe. To ważny krok w debugowaniu i optymalizacji kodu, pomagający w identyfikacji potencjalnych błędów i poprawie wydajności. Wybór wartości zmiennej kwoty może obejmować zarówno liczby dodatnie, jak i ujemne, a także zero, co rozszerza zakres testowania.

Podczas wprowadzania wartości równej 4,2 program zwraca niepoprawny wynik. Chociaż błąd jednej dziesiątej może wydawać się nieistotny w supermarkecie, może mieć poważne konsekwencje w transakcjach finansowych lub pomiarach naukowych. Błędy w obliczeniach mogą prowadzić do niewiarygodnych danych, co z kolei może mieć wpływ na ważne decyzje. Dlatego ważne jest, aby zwracać uwagę na dokładność obliczeń i upewnić się, że dane są poprawnie przetwarzane w oprogramowaniu. Spróbujmy naprawić ten błąd. Rozważmy sytuację, w której komputer przechowuje kwotę 4 dolarów i 19,99999 centów. Aby wyeliminować niedokładność, zaokrąglimy wynik. W tym celu dołączymy bibliotekę funkcji matematycznych math.h i zastosujemy funkcję round(), która jest dostępna w tej bibliotece. Użycie funkcji round() pomoże uzyskać poprawną wartość, unikając problemów związanych z liczbami zmiennoprzecinkowymi. Zapewni to dokładniejsze obliczenia i usprawni przetwarzanie danych finansowych w naszej aplikacji.
Uruchommy program ponownie.

Tekst został pomyślnie naprawiony.
Ważne jest, aby pamiętać o tych aspektach. Niestety, nawet doświadczeni programiści czasami zaniedbują te szczegóły. Celem naszych szkoleń jest nie tylko nauczenie Cię programowania, ale także zapewnienie Ci głębszego zrozumienia procesów zachodzących „pod maską” kodu oprogramowania. Ta wiedza pozwoli Ci stać się bardziej wykwalifikowanym specjalistą i poprawić jakość Twoich projektów.
Błędy technologiczne mogą mieć poważne konsekwencje, a społeczeństwo czasami płaci za nie wysoką cenę. Uderzającym przykładem jest sytuacja z błędem w systemie sterowania samolotu Boeing, który został ujawniony kilka lat temu. System ten wymagał regularnego restartu co 248 dni. W przeciwnym razie, podczas lotu, mógłby przejść w tryb awaryjny, co z kolei doprowadziłoby do wyłączenia generatora i potencjalnej katastrofy. Takie incydenty podkreślają wagę rygorystycznego testowania i monitorowania systemów zapewniających bezpieczeństwo transportu lotniczego.
Problem pojawił się, ponieważ oprogramowanie wykorzystywało 32-bitową liczbę do śledzenia dziesiętnych części sekundy, co miało wpływ na parametry zasilania elektrycznego generatorów. Po 248 dniach nastąpiło przepełnienie, co doprowadziło do przerwy w dostawie prądu. Rozwiązaniem Boeinga było zastosowanie 32-bitowego systemu operacyjnego. Firma wydała łatkę, która usuwa tę lukę, zapewniając stabilne działanie systemu i zapobiegając awariom.
Wraz ze wzrostem liczby urządzeń przenośnych i sprzętu, stajemy przed coraz większymi wyzwaniami. Każdy nowy gadżet niesie ze sobą nie tylko wygodę, ale także potencjalne komplikacje, takie jak kompatybilność, bezpieczeństwo i konieczność regularnych aktualizacji. Im więcej technologii wykorzystujemy, tym ważniejsze jest zrozumienie, jak skutecznie nimi zarządzać i minimalizować pojawiające się trudności.
Podsumowanie
Dzisiejszy wykład dotyczył ważnych aspektów tematu. Omówiliśmy kluczowe punkty, które pomogą Ci lepiej zrozumieć temat. Główny nacisk położono na główne koncepcje i metody, które można zastosować w praktyce. Przyjrzeliśmy się przykładom ilustrującym zasady teoretyczne i odpowiedzieliśmy na pytania, które pojawiły się podczas dyskusji. Należy pamiętać, że dogłębne zrozumienie materiału wymaga ciągłej nauki i praktyki. Mamy nadzieję, że zdobyta wiedza przyda się w przyszłej pracy.
- Jeśli planujesz wielokrotnie używać wyniku obliczenia w kodzie, zapisz go w osobnej zmiennej.
- Możesz nacisnąć strzałkę w górę w edytorze kodu, aby wyświetlić całą historię poleceń i wybrać potrzebne, zamiast wpisywać wielokrotnie to samo. Przyspieszy to Twoją pracę.
- Uważaj na problem przepełnienia podczas pracy z typami danych int i float — wszystkie one używają skończonej liczby bitów do reprezentacji. Używaj typu danych long, aby uniknąć tego problemu.
- W C deklaracja funkcji zawsze znajduje się na początku programu. W niektórych innych językach programowania, takich jak Python, funkcje można deklarować w dowolnym miejscu kodu.
- Aby poprawnie zaokrąglać liczby, użyj funkcji round() z biblioteki funkcji matematycznych math.h.
Dowiedz się więcej o programowaniu i kodowaniu na naszym kanale Telegram. Zapisz się, aby być na bieżąco z najnowszymi wiadomościami i ciekawymi materiałami.
Przeczytaj także:
- Rozpoczynam naukę języka programowania C. CS50 po rosyjsku. Wykład 1.1
- Fatality: 5 najdroższych błędów w historii
- Liczby zmiennoprzecinkowe: czym są i jak działają

