Menu
Coddy logo textTech

Co to jest kompilator?

Kompilator to program, który tłumaczy kod źródłowy napisany w języku programowania na kod maszynowy albo na inną postać niższego poziomu, taką jak kod bajtowy, zanim program zostanie uruchomiony. Przetłumaczony program może potem działać bez oryginalnego kodu źródłowego.

Autor: Kevin Spektor, Współzałożyciel i CTO

Aktualizacja: 24 września 2026

Kod źródłowy
  1. 1print("Hello")
  2. 2total = 2 + 3
  3. 3print(total)
  4. 4print("Done")
Wynik
Liczba kompilacji0
Uruchomienia0

Skompiluj raz, a potem uruchamiaj program, ile razy chcesz: licznik uruchomień rośnie, licznik kompilacji nie. Włącz literówkę, a kompilator odrzuci cały program, więc nic się nie wyświetli.

Zapisz ten program w C jako hello.c:

#include <stdio.h>

int main(void) {
    int price = 4;
    printf("Total: %d\n", price * 3);
    return 0;
}

Potem wpisz gcc hello.c -o hello. Przez chwilę nic widocznego się nie dzieje, a potem obok kodu źródłowego pojawia się nowy plik o nazwie hello. Ten plik to wynik pracy kompilatora: kod maszynowy, który twój procesor może wykonać. Usuń hello.c, a ./hello nadal działa, bo wszystko, czego program potrzebuje, zostało już przetłumaczone.

gcc hello.c -o hello
./hello
Total: 12

Jak działa kompilator krok po kroku

Kompilator czyta kod źródłowy jako zwykły tekst i przetwarza go etapami. Weźmy jedną linię total = price * 3:

  1. Analiza leksykalna. Tekst jest dzielony na tokeny, czyli "słowa" języka: nazwę total, operator =, nazwę price, operator * i liczbę 3. Spacje i komentarze są tu odrzucane.
  2. Parsowanie. Tokeny są układane w drzewo składniowe, które zapisuje strukturę: przypisanie, którego wartością jest mnożenie price przez 3. Kod, który łamie gramatykę języka, zatrzymuje się tutaj z błędem składni.
  3. Analiza semantyczna. Kompilator sprawdza znaczenie: czy price jest zadeklarowane, czy typy są zgodne, czy wywoływana funkcja istnieje.
  4. Optymalizacja. Program jest przepisywany tak, żeby działał szybciej albo zużywał mniej pamięci, bez zmiany tego, co robi. x * 2 może stać się jedną instrukcją przesunięcia, a kod, który nigdy się nie wykona, zostaje usunięty.
  5. Generowanie kodu. Kompilator zapisuje wynik dla wybranego celu: kod maszynowy x86-64 albo ARM albo kod bajtowy dla maszyny wirtualnej.

W C i C++ ostatni krok, linkowanie, łączy twoje skompilowane pliki z kodem bibliotek (na przykład printf ze standardowej biblioteki C) w jeden plik wykonywalny. gcc uruchamia linker za ciebie, dlatego wygląda to na jedno polecenie.

Python udostępnia pierwsze dwa etapy jako standardowe moduły, więc możesz zobaczyć, jak działają na prawdziwych danych:

NAME 'total'
OP '='
NAME 'price'
OP '*'
NUMBER '3'
Assign(
  targets=[
    Name(id='total', ctx=Store())],
  value=BinOp(
    left=Name(id='price', ctx=Load()),
    op=Mult(),
    right=Constant(value=3)))

Na tym drzewie pracuje reszta kompilatora. Nie obchodzą go już spacje ani podziały linii, tylko struktura: przypisz do total wynik mnożenia price przez 3.

Czas kompilacji: błędy znalezione przed uruchomieniem

Ponieważ kompilator czyta cały program, zanim jakakolwiek jego część się wykona, może wcześnie odrzucić błędy. W tym przykładzie nie wykonuje się żadna z trzech linii print w source, nawet pierwsza, bo kompilator Pythona odrzuca tekst, zanim zacznie się wykonanie:

Rejected before running anything:
  '(' was never closed (line 3)

Kompilatory języków statycznie typowanych wyłapują więcej niż błędy składni. Ta linia w C, w pliku bad.c, jest poprawna gramatycznie, ale zapisuje tekst w zmiennej całkowitej:

int count = "five";

GCC 14 i nowsze zatrzymują się z błędem:

bad.c:4:17: error: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]

Ten sam błąd w Pythonie ujawniłby się dopiero przy wykonaniu tej linii. Wyłapywanie go w czasie kompilacji to jeden z powodów, dla których duże zespoły wybierają kompilowane języki ze statycznym typowaniem. Kompilator nie wyłapie jednak wszystkiego: dzielenie przez liczbę, która okazuje się zerem, albo odczyt nieistniejącego pliku nadal kończą się błędem w czasie wykonania.

Przykłady kompilatorów

KompilatorCzytaTworzy
GCC, ClangC, C++Kod maszynowy dla x86-64, ARM i innych
MSVC (Microsoft Visual C++)C, C++Pliki wykonywalne Windows (.exe, .dll)
javacJavaKod bajtowy JVM (pliki .class)
rustcRustKod maszynowy
go buildGoJeden plik wykonywalny
tscTypeScriptJavaScript

Dwa wiersze pokazują, że kod maszynowy nie jest jedynym możliwym wynikiem. javac tworzy kod bajtowy, który wykonuje wirtualna maszyna Javy, część środowiska uruchomieniowego Javy. tsc zamienia TypeScript na JavaScript, inny język wysokiego poziomu; kompilator, który tak działa, często nazywa się transpilatorem.

Skompilowany kod maszynowy jest związany z jedną rodziną procesorów i jednym systemem operacyjnym. Program skompilowany dla Windowsa na x86-64 nie uruchomi się na Macu z chipem Apple z serii M; ten sam kod źródłowy kompiluje się ponownie dla każdego celu.

Kompilator czy interpreter

Interpreter wykonuje kod źródłowy bezpośrednio, zamiast tworzyć osobny plik z programem, i tak zwykle uruchamia się Pythona i Ruby. Większość nowoczesnych narzędzi językowych łączy oba pomysły: CPython kompiluje twój plik do kodu bajtowego, a potem go interpretuje, a JVM i silnik V8 JavaScriptu kompilują często używany kod do kodu maszynowego w trakcie działania programu. Pełna tabela porównawcza jest na stronie kompilator a interpreter.

Częste nieporozumienia

  • "Jeśli się kompiluje, to działa." Kompilator sprawdza, czy program jest poprawny formalnie, a nie czy robi to, co trzeba. Błędy logiczne i awarie w czasie wykonania, takie jak dzielenie przez zero, przechodzą dalej.
  • "Python nie jest kompilowany." CPython kompiluje każdy plik do kodu bajtowego przed uruchomieniem. Pliki .pyc w folderach __pycache__ to właśnie ten kod bajtowy, zapisany dla modułów importowanych przez program, żeby następne uruchomienie mogło pominąć ten krok.
  • "Kompilator online to kompilator." Strony, które uruchamiają twój kod w przeglądarce, wysyłają go na serwer, który uruchamia cały zestaw narzędzi (kompilator, linker i sam program) i zwraca wynik. Kompilator to tylko jeden z tych elementów.
  • "Skompilowany kod działa wszędzie." Działa na procesorze i systemie operacyjnym, dla których został zbudowany. Przenośność daje ponowna kompilacja albo maszyna wirtualna, taka jak JVM.

Co dalej

Dokumentacja C pokazuje kompilator w codziennym użyciu: jak skompilować i uruchomić program w C prowadzi przez preprocesing, kompilację, asemblację i linkowanie z prawdziwymi poleceniami gcc. Żeby poznać drugi sposób uruchamiania kodu, przeczytaj kompilator a interpreter, a potem środowisko uruchomieniowe, czyli to, co otacza program po jego starcie. Kurs C to dobre miejsce, żeby poćwiczyć z językiem kompilowanym.

Najczęściej zadawane pytania

Z czego składa się kompilator?
Kompilator zwykle opisuje się jako trzy części. Front end czyta kod źródłowy, dzieli go na tokeny, parsuje do drzewa składniowego i sprawdza typy. Middle end optymalizuje pośrednią postać programu, a back end generuje kod maszynowy albo kod bajtowy dla docelowego procesora.
Jak kompilator może skompilować sam siebie?
Dzięki bootstrappingowi. Pierwszą wersję kompilatora pisze się w istniejącym języku albo kompiluje starszym kompilatorem, a potem używa się jej do skompilowania kolejnej wersji napisanej już w nowym języku. GCC jest na przykład napisany głównie w C i C++ i buduje się go istniejącym kompilatorem C++, często wcześniejszą wersją GCC.
Czym różni się kompilator od asemblera?
Kompilator tłumaczy język wysokiego poziomu, taki jak C albo Rust, w którym jedna linia może stać się wieloma instrukcjami maszynowymi. Asembler tłumaczy język asemblera, w którym każda linia odpowiada niemal jeden do jednego pojedynczej instrukcji maszynowej. Kompilatory takie jak GCC często najpierw tworzą kod asemblera i przekazują go asemblerowi.
Co to jest kompilator JIT?
Kompilator just-in-time (JIT) tłumaczy kod na kod maszynowy w trakcie działania programu, a nie przed nim. Obserwuje, które części wykonują się najczęściej, i kompiluje właśnie je, więc długo działający program z czasem przyspiesza. Kompilacji JIT używają JVM, silnik V8 JavaScriptu i PyPy.
Czy muszę instalować kompilator, żeby uczyć się programowania?
Na początku nie. Edytory w przeglądarce i edytory online uruchamiają kompilator albo interpreter na serwerze za ciebie. Gdy przejdziesz na własny komputer, C i C++ potrzebują kompilatora takiego jak GCC albo Clang, Java potrzebuje JDK, a Python interpretera Pythona.
Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ