Repozytorium zawiera materiały do przedmiotu Computer Science 1 / Podstawy Programowania dla studentów studiów inżynierskich Politechniki Warszawskiej.
Materiały mają interaktywną formę i można je uruchomić przez:
Od zera do bohatera.
Kurs jest przeznaczony dla osób, które nigdy wcześniej nie programowały. Jego celem nie jest możliwie szybkie nauczenie jednego konkretnego języka programowania. Chcemy przede wszystkim zbudować solidne zrozumienie podstawowych pojęć programistycznych i myślenia algorytmicznego.
Języki programowania się zmieniają.
Narzędzia się zmieniają.
Biblioteki i frameworki się zmieniają.
Podstawowe koncepcje pozostają.
Uczymy się, jak opisać problem w postaci algorytmu, a następnie jak przekształcić ten algorytm w działający program.
Zaczynamy od absolutnych podstaw:
- zmiennych i typów danych,
- operacji arytmetycznych i logicznych,
- operacji wejścia i wyjścia,
- instrukcji warunkowych,
- pętli,
- funkcji i dzielenia problemu na mniejsze części,
- pamięci, adresów i wskaźników,
- tablic,
- plików,
- dynamicznej alokacji pamięci,
- pracy z tekstem (string),
- struktur.
Po drodze poznajemy również podstawowe zagadnienia algorytmiczne: iterację, przetwarzanie zbiorów danych, sortowanie, proste obliczenia numeryczne oraz pierwsze pojęcia związane z kosztem algorytmu.
Chcemy rozumieć co komputer rzeczywiście robi, a nie jedynie wiedzieć, jakie polecenie należy wpisać.
Bardzo naturalne jest pytanie:
Po co dzisiaj uczyć się C? Czy nie lepiej od razu zacząć od czegoś nowocześniejszego, jak Python albo Java?
Języki "wysokopoziomowe" takie jak Python są niezwykle użyteczne. Jednocześnie bardzo skutecznie ukrywają przed programistą wiele szczegółów działania programu.
Na tym kursie celowo chcemy te szczegóły zobaczyć.
W C:
- dane mają jawnie określony typ (statyczne typowanie),
- różne typy zajmują różną ilość pamięci,
- zmienna znajduje się pod konkretnym adresem,
- możemy jawnie pracować z adresami,
- tablica ma konkretną reprezentację w pamięci,
- przekazanie wartości do funkcji i przekazanie adresu to dwie różne rzeczy,
- pamięć dynamiczną trzeba samodzielnie przydzielić i zwolnić,
- napis nie jest magicznym obiektem — jest odpowiednio zorganizowanym fragmentem pamięci,
- programista odpowiada za wiele operacji, które języki wyższego poziomu wykonują automatycznie.
To sprawia, że C bywa wymagający. Właśnie dlatego jest również bardzo dobrym językiem dydaktycznym.
Jeżeli coś działa, chcemy wiedzieć dlaczego.
Jeżeli coś nie działa, chcemy wiedzieć co dokładnie poszło źle.
Celem kursu nie jest przekonywanie, że wszystkie przyszłe programy należy pisać w C. Chodzi o pokazanie mechanizmów, które języki wyższego poziomu często przed nami ukrywają.
Kiedy te mechanizmy zostaną zrozumiane, nauka kolejnego języka jest znacznie łatwiejsza. Python, C++, Java, Rust, Julia czy MATLAB oferują inną składnię i inne abstrakcje, ale pod nimi nadal znajdują się te same podstawowe idee: dane, operacje, przepływ sterowania, funkcje, pamięć i algorytmy.
Programowanie obiektowe jest ważne, ale nie jest przedmiotem tego kursu.
Zanim zaczniemy mówić o klasach, dziedziczeniu, polimorfizmie czy wzorcach projektowych, chcemy dobrze rozumieć bardziej podstawowe elementy programu:
dane → operacje → decyzje → iteracja → funkcje → pamięć → struktury danych
Dlatego koncentrujemy się na programowaniu proceduralnym i strukturalnym.
Najpierw chcemy nauczyć się rozwiązywać problemy za pomocą programu. Dopiero później przychodzi czas na bardziej zaawansowane sposoby organizowania dużych systemów programistycznych.
Po ukończeniu przedmiotu powinieneś potrafić:
- przeanalizować prosty problem obliczeniowy lub inżynierski,
- sformułować algorytm jego rozwiązania,
- przekształcić algorytm w uporządkowany program,
- świadomie korzystać z warunków, pętli i funkcji,
- rozumieć podstawowe typy danych i ich konwersje,
- rozumieć związek pomiędzy zmienną a pamięcią komputera,
- posługiwać się wskaźnikami i tablicami,
- rozróżniać dane statyczne od dynamicznie alokowanych,
- odczytywać i zapisywać dane do plików,
- pracować z napisami i strukturami,
- rozpoznawać typowe błędy programistyczne,
- czytać i rozumieć stosunkowo proste programy w C,
- podejść do nauki nowego języka ze zrozumieniem koncepcji kryjących się pod jego składnią.
Najważniejszym efektem kursu nie jest zapamiętanie składni C (to i tak będziesz musiał zrobić).
Najważniejsze jest nauczenie się myślenia programistycznego.
Programowania nie da się nauczyć wyłącznie przez czytanie slajdów albo obserwowanie, jak ktoś inny pisze kod.
Pod tym względem przypomina ono matematykę, naukę gry na instrumencie albo robienie pompek:
trzeba ćwiczyć.
Czytaj przykłady.
Kompiluj je.
Modyfikuj.
Psuj.
Sprawdzaj, dlaczego przestały działać.
Pisz własne programy.
Małe eksperymenty są jednym z najlepszych sposobów nauki programowania.
Repozytorium zawiera slajdy wykładowe, notebooki Jupyter oraz programy źródłowe używane podczas zajęć. Wiele przykładów jest celowo bardzo prostych, tak aby można było przyjrzeć się pojedynczej koncepcji bez zaciemniania jej niepotrzebną złożonością.
Repozytorium jest uporządkowane zgodnie z kolejnymi wykładami.
Materiał prowadzi w przybliżeniu przez następujące zagadnienia:
- Wprowadzenie do programowania i języka C
- Typy danych i wyrażenia
- Wejście/wyjście i funkcje matematyczne
- Instrukcje warunkowe i funkcje
- Pętle i strukturalne sterowanie przebiegiem programu
- Pamięć, adresy i wskaźniki
- Tablice jednowymiarowe, sortowanie i pliki
- Przetwarzanie danych z użyciem plików
- Tablice dwuwymiarowe i pamięć dynamiczna
- Dynamiczne tablice jedno- i dwuwymiarowe
- Napisy
- Struktury i dalsze zastosowania
Repozytorium zawiera również wiele małych programów w C ilustrujących omawiane na wykładzie zagadnienia.
Wykład 1: aktualnym materiałem wykładowym jest notebook 1/Wykład 1.ipynb. Pliki 1/Lecture 1 examples.ipynb oraz 1/lec1.tex / 1/lec1.pdf pozostają w repozytorium jako materiały historyczne i referencyjne.
Wykład 2 (modernizacja zakończona): roboczy notebook 2/Wykład 2.ipynb jest rozwijany etapami. W2.0: PASS zgłoszony przez prowadzącego 14.10.2026; kopia zgodna z historycznym notebookiem (Git blob a33d1194, commit 3a3a15d8). W2.1: VERIFIED PASS (14.10.2026), commit c9b083b2 — potwierdzono na dodo właściwy HEAD, 70 komórek, 33 komórki C, kernel c oraz poprawne ładowanie notebooka; niezależna weryfikacja w C11 potwierdziła wyniki a+b=11 i a+b=14 (brak osobnego logu wykonania tych komórek w Jupyterze). W2.2: VERIFIED PASS (14.10.2026), commit 8f8fabeb — prowadzący potwierdził na dodo poprawne działanie notebooka, kernela C i eksperymentów sizeof. W2.3: VERIFIED PASS (14.10.2026), commit ff8f724e — prowadzący potwierdził prawidłowe wyniki wszystkich czterech nowych eksperymentów w Jupyterze (deklaracje, trzy zapisy liczby, różne wartości oraz formatowanie). W2.4: VERIFIED PASS (14.10.2026), commit fddae871 — prowadzący zaakceptował uproszczone przykłady, reprezentację int w uzupełnieniach do dwóch oraz rozszerzoną tabelę 8-bitową z wyjaśnieniem zakresu. Wcześniejsza wersja f7cc7eba przeszła 5/5 testów GCC, lecz została uproszczona; zaobserwowane na dodo zawinięcie przepełnienia int nie jest gwarancją standardu C. W2.5: VERIFIED PASS (14.10.2026), commit 8aa2aa8e — prowadzący przesłał log z dodo: testy 3/3 nowych komórek (45, 48, 51), GCC C11 z -Wall -Wextra -pedantic -Werror, poprawne wyniki działań i reszt także dla liczb ujemnych; struktura 98 komórek, 38 C, kernel c. W2.6: 15.10.2026 — pięć przetestowanych programów GCC (commit 53784e0d) nadal ma PASS. Na podstawie kolejnego przeglądu dydaktycznego objaśniono zapis (1.F)₂ i wyjątek zer E=0,F=0 oraz liczb podnormalnych E=0,F!=0, ujednolicono nazwy kolumn Znak S, Wykładnik E, Część ułamkowa F, dodano dziesiętną znaczącą m=1+F/2^p i przykład zamiany 13 cyfr hex na 52 bity dla double. Nie zmieniono kodu C ani zapisanych wyników z dodo. VERIFIED PASS (15.10.2026), commit 0d9684b6 — prowadzący potwierdził na dodo HEAD, 109 komórek, 38 komórek C, kernel c, test struktury oraz czytelność nowych tabel (zrzut Jupyter); pięć przykładów C przeszło wcześniej testy, a ich kod nie był zmieniany. Dodatkowo doprecyzowano, że E=0,F≠0 daje liczbę podnormalną bez ukrytej jedynki i z wykładnikiem 1-bias. W2.7: VERIFIED PASS (15.10.2026), commit 89ffe27c — prowadzący przesłał log z dodo potwierdzający master HEAD, strukturę 114 komórek / 39 komórek C, kernel c i poprawne wyniki 4/4 przykładów GCC C11 z rzutowaniem, konwersją double↔int i utratą dokładności int→float. W2.8: VERIFIED PASS (15.10.2026), commit c013c582 — prowadzący potwierdził HEAD na dodo, poprawną strukturę 122 komórek / 40 komórek C, wykonanie 3/3 nowych przykładów GCC C11 (char, '0' / 0 / "0", signed char / unsigned char) i prawidłowy rendering tabeli liczb podnormalnych. W dodatkowym commicie rozszerzono tabelę W2.6 o najmniejszą i drugą najmniejszą dodatnią liczbę podnormalną binary32, przywrócono historyczny link do ASCII i dodano pełną tabelę ASCII 0–127 (16×8). Wszystkie programy C z W2.8 pozostały nietknięte; prowadzący potwierdził na dodo aktualizację do commita 30882aaa, strukturę 123 komórek / 40 komórek C oraz PASS testu obejmującego dwie najmniejsze dodatnie podnormalne i pełną tabelę ASCII 0–127. Uzupełnienie W2.8 i W2.6: VERIFIED PASS. W2.9: VERIFIED PASS (15.10.2026), commit c16a28f — prowadzący potwierdził na dodo HEAD c16a28f1209f19b5f3920b5bcdb10a8430d41e02, strukturę 129 komórek / 42 komórki C, kernel c oraz 3/3 testy GCC C11 (bool, konwersja 0 i wartości niezerowych, operatory porównania). W2.10: VERIFIED PASS (15.10.2026), commit 81699578b8604e6fdc52c6e0d5e00c2f5ffad51a — prowadzący potwierdził HEAD na Linux, 136 komórek i 44 komórki C, kernel c; dwa nowe programy void zwróciły oczekiwane wyniki, a trzeci został celowo odrzucony przez GCC C11 z diagnostyką variable or field 'wynik' declared void. Dodatkowe ostrzeżenie o niewykorzystanej zmiennej jest uboczne i nie zmienia wyniku bramki. Opis konfiguracji odniesienia Linux/x86-64, GCC, C11 został zweryfikowany. W2.11: VERIFIED PASS (15.10.2026), commit 3d165722e2296b7cb7dfc8150c158277251b2015 — prowadzący potwierdził aktualizację master, 137 komórek / 41 komórek C i poprawne wyniki wszystkich pięciu programów przy GCC C11 -O0 oraz -O2 (10/10 PASS). W2.12: integracja W1/W2, numeracja rozdziałów W2.1–W2.11, usunięcie 6 redundantnych anglojęzycznych komórek końcowych (funkcje omówione w W1 i W2.10), podsumowanie i pytania kontrolne po polsku, wyczyszczenie wyników wykonania wszystkich komórek, rozróżnienie celowego UB przepełnienia int i oczekiwanego błędu deklaracji void; dodano pełną walidację python3 2/check_w2.py (35 poprawnych programów × 2 warianty optymalizacji, 2 specjalne eksperymenty; komplet oczekiwanych wyjść dla Linux/x86-64 GCC C11). Historyczne materiały i W1 pozostają nietknięte. AUTOMATED REGRESSION VERIFIED PASS dla commita ef105178f6dcc47ec5a8b1d28f95c9512ae710c0: prowadzący uruchomił python3 2/check_w2.py, uzyskał 35/35 poprawnych programów C z wynikami zgodnymi z oczekiwanymi przy -O0 i -O2 (70/70 uruchomień), poprawne rozpoznanie celowego UB i błędu void, PASS struktury, ASCII, zgodności W1 i zachowania materiałów historycznych; po teście stan śledzonych plików był czysty. Po tym teście autor zaktualizował W1 (836b06f, f4b6a78) i W2 (78dd4a0), w tym zmienił etykietę sizeof liczba na sizeof(liczba) i liczbę komórek W2 z 134 na 133. Dostosowano wyłącznie 2/check_w2.py i README do aktualnego materiału: oczekiwana etykieta, pin W1, identyfikacja przypadków przez kolejność komórek C, niezależna od liczby komórek Markdown. W2.12: VERIFIED PASS (15.10.2026; commit 67d7fa4) — regresja i modernizacja W2 zakończone. Wyjaśniono też sufiks 1u przy wcześniejszym przykładzie unsigned int. Pliki 2/Lecture 2 Examples.ipynb oraz 2/lec2.tex / 2/lec2.pdf pozostają materiałami historycznymi i referencyjnymi.
Wykład 3 (aktualny materiał): 3/Wykład 3.ipynb — polski notebook Jupyter z kernelem C; główne tematy: printf, scanf (w notebooku deterministyczne doświadczenia sscanf, interaktywny scanf w niezależnej konsoli), <math.h>, sprawdzanie wartości zwracanych i błędnego wejścia. Instrukcje oraz testy: 3/README.md i python3 3/check_w3.py. 3/Lecture 3 Examples.ipynb i 3/lec3.pdf pozostają historyczne.
Lecture materials for the Computer Science 1 / Programming Fundamentals course for engineering students at the Warsaw University of Technology.
From Zero to Hero.
This course is intended for students who may have never programmed before. Its goal is not to teach one particular programming language as quickly as possible. The goal is to build a solid understanding of the fundamental ideas of programming and algorithmic thinking.
Programming languages change. Tools change. Libraries and frameworks change. The basic concepts do not.
During the course we learn how to describe a problem as an algorithm and how to translate that algorithm into a working program.
We start from the very beginning:
- variables and data types,
- arithmetic and logical operations,
- input and output,
- decisions and branching,
- loops,
- functions and decomposition of a problem into smaller parts,
- memory, addresses and pointers,
- arrays,
- files,
- dynamic memory allocation,
- strings,
- structures.
Along the way we also introduce basic algorithmic ideas: iteration, searching and processing data, sorting, working with collections of values, numerical examples and reasoning about the cost of an algorithm.
The intention is to understand what the computer is actually doing, rather than only learning which command to type.
A natural question is:
Why learn C today? Why not simply start with Python?
Python is an excellent and extremely useful language. It is also very good at hiding many details from the programmer.
For an introductory course, we deliberately want to expose those details.
In C:
- data has an explicit type,
- different types occupy different amounts of memory,
- variables live somewhere in memory,
- addresses can be inspected and manipulated,
- arrays have a concrete representation,
- passing a value and passing an address are different operations,
- dynamic memory must be explicitly allocated and released,
- strings are not magical objects — they are data stored in memory,
- the programmer has direct responsibility for many operations that higher-level languages perform automatically.
This makes C demanding, but it also makes it an excellent teaching language.
When something works, we want to understand why it works.
When something fails, we want to understand what went wrong.
The purpose is not to convince you that every future program should be written in C. The purpose is to make the mechanisms hidden by higher-level languages visible.
Once these ideas are understood, learning another programming language becomes much easier. Python, C++, Java, Rust, Julia, MATLAB and many others provide different abstractions and syntax, but underneath them remain the same fundamental ideas: data, operations, control flow, functions, memory and algorithms.
Object-oriented programming is important, but it is not the subject of this course.
Before introducing classes, inheritance, polymorphism and design patterns, we want to understand the more fundamental building blocks of a program:
data → operations → decisions → iteration → functions → memory → data structures
The course therefore concentrates on procedural and structured programming.
The objective is to learn how to solve a problem with a computer before learning more advanced ways of organising large software systems.
After completing the course, you should be able to:
- analyse a simple engineering or computational problem,
- formulate an algorithm solving it,
- translate the algorithm into a structured program,
- use conditions, loops and functions consciously,
- understand basic data types and conversions,
- understand the relation between variables and memory,
- use pointers and arrays,
- distinguish between static and dynamically allocated data,
- read and write data files,
- work with strings and structures,
- recognise common programming errors,
- read and understand relatively simple C programs,
- approach a new programming language with an understanding of the concepts behind its syntax.
The most important outcome is not memorising C syntax.
The most important outcome is to be able to think like a programmer.
Programming cannot be learned only by reading slides or watching someone else write code.
It is much closer to learning mathematics, playing an instrument, or doing push-ups:
you need practice.
Read the examples.
Compile them.
Change them.
Break them.
Try to understand why they stopped working.
Write your own programs.
Small experiments are one of the best ways to learn.
The repository contains lecture slides, Jupyter notebooks and source-code examples used during the course. Many examples are intentionally simple so that a single programming concept can be examined in isolation.
The repository is organised according to consecutive lectures.
The material progresses roughly through:
- Introduction to programming and C
- Data types and expressions
- Input/output and mathematical functions
- Branching and functions
- Loops and structured control flow
- Memory, addresses and pointers
- One-dimensional arrays, sorting and files
- File-based data processing
- Two-dimensional arrays and dynamic memory
- Dynamic one- and two-dimensional arrays
- Strings
- Structures and further applications
The repository also contains numerous small C programs illustrating the concepts discussed during lectures.
Lecture 1: the current lecture material is 1/Wykład 1.ipynb. The files 1/Lecture 1 examples.ipynb and 1/lec1.tex / 1/lec1.pdf are retained as historical/reference material.
Lecture 2 (modernisation complete): 2/Wykład 2.ipynb is the working lecture notebook. W2.0: instructor-reported PASS on 2026-10-14; the copy matched the historical notebook (Git blob a33d1194, commit 3a3a15d8). W2.1: VERIFIED PASS (2026-10-14), commit c9b083b2 — dodo confirmed correct HEAD, 70 cells, 33 C cells, kernel c, and notebook loading; independent C11 execution confirmed a+b=11 and a+b=14 (no separate Jupyter execution log supplied). W2.2: VERIFIED PASS (2026-10-14), commit 8f8fabeb — instructor confirmed on dodo that the notebook, C kernel and sizeof experiments work. W2.3: VERIFIED PASS (2026-10-14), commit ff8f724e — instructor confirmed expected outputs for all four new Jupyter examples (variable assignment, equivalent literals, distinct literal values, and output formatting). W2.4: VERIFIED PASS (2026-10-14), commit fddae871 — instructor accepted simplified examples and the 8-/32-bit two's-complement explanation with completed 8-bit table. Previous f7cc7eba passed 5/5 focused GCC tests but was replaced with a simpler presentation; observed signed-overflow wrapping on dodo is not guaranteed by C. W2.5: VERIFIED PASS (2026-10-14), commit 8aa2aa8e — instructor submitted dodo evidence for all three new examples (45, 48, 51), compiled with GCC C11 and -Wall -Wextra -pedantic -Werror; results match expected integer operations and signed division/remainders, 98 cells, 38 C code cells, kernel c. W2.6: 2026-10-15 — five previously checked C examples (commit 53784e0d) remain PASS. Further teaching review clarified (1.F)₂, signed zero (E=0,F=0), subnormals (E=0,F!=0), consistent field labels, decimal significands m=1+F/2^p, and 13-hex-digit to 52-bit fraction decoding for double. C code and instructor-saved outputs are unchanged. VERIFIED PASS (2026-10-15), commit 0d9684b6 — instructor confirmed dodo HEAD, 109 cells, 38 C cells, c kernel, structural checks and readable tables in Jupyter; five previously tested C programs were unchanged. Additional clarification: E=0,F!=0 is subnormal, with no implicit leading one and exponent 1-bias. W2.7: VERIFIED PASS (2026-10-15), commit 89ffe27c — instructor supplied dodo log confirming master HEAD, 114 cells / 39 C cells, c kernel and expected GCC C11 outputs for all four conversion/casting examples, including integer-to-float precision loss. W2.8: VERIFIED PASS (2026-10-15), commit c013c582 — instructor confirmed dodo HEAD, 122 cells / 40 C code cells, 3/3 GCC C11 examples working (char, character/string/numeric zero, signed/unsigned char), and correct rendering of the subnormal table. Additional Markdown update extends W2.6 with smallest and second-smallest positive binary32 subnormals, restores the original ASCII reference link, and adds a complete 0–127 ASCII chart (16×8). All prior W2.8 C programs remain untouched; instructor confirmed dodo update to commit 30882aaa, 123 cells / 40 C cells and PASS of the structural tests covering the two smallest positive subnormals and full ASCII table 0–127. W2.8/W2.6 supplemental Markdown: VERIFIED PASS. W2.9: VERIFIED PASS (2026-10-15), commit c16a28f — instructor supplied dodo HEAD c16a28f1209f19b5f3920b5bcdb10a8430d41e02, structure 129 cells / 42 C cells, c kernel and passing results for all 3 GCC C11 tests (bool basics, 0/nonzero conversion and comparison). W2.10: VERIFIED PASS (2026-10-15), commit 81699578b8604e6fdc52c6e0d5e00c2f5ffad51a — instructor confirmed Linux HEAD, 136 total cells and 44 C cells, c kernel; both positive void-function examples passed, and the intentional invalid void object was rejected by GCC C11 with variable or field 'wynik' declared void. The secondary unused-variable warning is non-blocking. Reference environment Linux/x86-64, GCC, C11 prose was verified. W2.11: VERIFIED PASS (2026-10-15), commit 3d165722e2296b7cb7dfc8150c158277251b2015 — instructor confirmed the master SHA, 137 cells / 41 C cells and expected outputs of five operator programs with GCC C11 under both -O0 and -O2 (10/10 PASS). W2.12: W1/W2 integration, consistent W2.1–W2.11 section headings, removal of six redundant English tail cells (functions already covered in W1 and W2.10), Polish summary and practice questions, clearing all saved execution outputs, distinct tags for signed-overflow UB and invalid void-object declaration; full regression python3 2/check_w2.py (35 valid C programs at two optimisation levels, two special cases, all golden outputs for Linux/x86-64 GCC C11). Historical files and W1 remain untouched. AUTOMATED REGRESSION VERIFIED PASS for ef105178f6dcc47ec5a8b1d28f95c9512ae710c0: instructor ran python3 2/check_w2.py, confirming 35/35 valid C programs and all 70 GCC C11 -O0/-O2 runs, intentional UB syntax-only test, intentional invalid void diagnostic, W1/ASCII/notebook structure, historical provenance and no tracked changes afterward. Instructor subsequently updated W1 (836b06f, f4b6a78) and W2 (78dd4a0), changing the sizeof output label and W2 cell count (134 to 133). 2/check_w2.py was adapted for the newer material: exact output label, updated W1 provenance, and code-cell ordinal rather than fragile absolute notebook indices. W2.12: VERIFIED PASS (2026-10-15; commit 67d7fa4) — W2 regression and modernisation completed. Added an explanatory note for 1u in the preceding unsigned example. The files 2/Lecture 2 Examples.ipynb and 2/lec2.tex / 2/lec2.pdf remain historical/reference material.
Lecture 3 (current material): 3/Wykład 3.ipynb is the Polish C-kernel notebook on printf, scanf, input validation and <math.h>. Notebook experiments use sscanf; interactive scanf is run in an independent terminal. See 3/README.md and python3 3/check_w3.py. Historical English notebook and PDF are retained for reference.