رابین؛ مشاور معتمد...

C język programowania Wikipedia, wolna encyklopedia

فهرست مطالب

Środowiska wykonawcze dla programów napisanych w innych językach również powstają z wykorzystaniem kodu w C. Java Runtime Environment[139], CPythona (referencyjnej implementacji Pythona)[140] czy interpretera PHP[141]. Ponadto C bywa także stosowany jako język pośredni dla kompilatorów języków wyższego poziomu. Niektóre języki wymagają jednak cech, których C nie oferuje, np.

  1. Dodatków tych nie wcielono do C, a C++ został niezależnie ustandaryzowany przez ANSI i ISO[12].
  2. Od standardu C99 zdefiniowany jest sposób obsługi liczb zespolonych w języku.
  3. Tę klasę pamięci można również określić jawnie słowem kluczowym auto[108].
  4. Zarezerwowany w ten sposób zakres, w zależności od wywołanej funkcji, może być zainicjalizowany samymi zerami, lecz nie musi.
  5. Jest to domyślna własność zmiennych deklarowanych na zewnątrz funkcji[114].

Przykład „Hello world”[edytuj edytuj kod]

Zarezerwowany w ten sposób zakres, w zależności od wywołanej funkcji, może być zainicjalizowany samymi zerami, lecz nie musi. Czas życia obiektów w alokowanej jawnie pamięci trwa od jej przydzielenia aż do zwolnienia za pomocą funkcji free[117]. Standard języka C definiuje również typy atomowe, choć stanowią one opcjonalną funkcjonalność, która nie musi być obsługiwana przez implementacje[88]. Na zmianę wartości zmiennych takich typów w sposób atomowy, tj. Z gwarancją, że operacja nie zostanie przerwana przez inne działanie na tej samej zmiennej[89]. Obiekt (zwany też zmienną[41]), według standardu języka C, to region pamięci środowiska wykonawczego, mogący reprezentować wartości[42].

Typy podstawowe[edytuj edytuj kod]

Jeszcze przed publikacją książki do języka C włączono kwalifikatory short i long, pozwalające określić wielkość zmiennej typu całkowitoliczbowego, a także specyfikator unsigned, oznaczający liczby nieujemne[9]. Z kolei w PYPL – alternatywnym rankingu popularności języków programowania – liczone łącznie języki C i C++ osiągnęły w czerwcu 2022 piątą lokatę[146]. Zastosowanie języka C pozwoliło części producentów oprogramowania zrezygnować ze stosowania języka asemblera[130]. Z Oracle Database w 1983 roku, co pozwoliło na osiągnięcie jego przenośności. W konsekwencji, Oracle Database 3 stało się pierwszym silnikiem relacyjnych baz danych, który można było uruchomić zarówno na komputerach typu mainframe, minikomputerach jak i komputerach osobistych[133]. W C został napisany również najpopularniejszy na świecie silnik bazodanowy, SQLite[134].

Instrukcje sterujące[edytuj edytuj kod]

W książce Kernighana i Ritchiego znalazł się również opis biblioteki wejścia/wyjścia. Podwaliny pod nią położył w 1972 roku Mike Lesk, pisząc „przenośną bibliotekę wejścia/wyjścia”. W następnych latach, wraz z pracami nad przenośnością systemu Unix, została ona rozwinięta i usprawniona. Funkcje biblioteczne nie zostały przez autorów książki uznane za część języka, lecz dodatek do niego[4][10]. Około 1977 roku Dennis Ritchie, Ken Thompson i Stephen Johnson skupili się na przenośności oprogramowania napisanego w C[4].

Zarządzanie pamięcią[edytuj edytuj kod]

C – imperatywny, proceduralny język programowania ogólnego przeznaczenia[3], stworzony na początku lat 70. XX wieku przez Dennisa Ritchiego, ówczesnego pracownika Bell Labs. W języku C powstały narzędzia systemowe dla Uniksa, a potem również kod systemu Unix. Od tego czasu jego rozwojem zajmuje się grupa robocza w ramach ISO. Cechy języka, krytykowane jako trudne do odczytania lub zrozumienia, bywają również wykorzystywane do celowego zaciemniania kodu, czego skrajnym przypadkiem są programy zgłaszane do konkursu IOCCC[170].

ANSI C i ISO C[edytuj edytuj kod]

Implementacje wspierające wersję C99 powinny ustawić makro __STDC_VERSION__ na [20]. Język taki, jak opisany przez Kernighana i Ritchiego w 1978 roku nie przewidywał żadnej możliwości określenia typów przyjmowanych przez parametry Różnica między ICO i IPO funkcji[4]. Powstały odrębne narzędzia, takie jak lint, które przeprowadzały analizę kodu bardziej rygorystyczną niż kompilator, a następnie zgłaszały problemy ze spójnością i przestrzeganiem dobrych praktyk[6].

Wczesny rozwój[edytuj edytuj kod]

Z tego też powodu C bywa nazywany „wysokopoziomowym asemblerem”[130]. W praktyce dla każdej nowej architektury język C jest pierwszym dostępnym językiem programowania poza asemblerem[132]. Istnieje również klasa pamięci _Thread_local, której czas życia jest powiązany z wątkiem.

Ponadto zapewniał w tamtym czasie najpełniejsze wsparcie dla programowania strukturalnego, pozwalając również na hermetyzację kodu[130]. Zastosowanie ręcznej alokacji pamięci może prowadzić do wystąpienia błędów w kodzie, wynikających np. Z odwołań do wiszących wskaźników(inne języki), ale także przepełnienia bufora i próby powtórnej dealokacji. Obecne w programie podatności mogą zależeć od wykorzystanego algorytmu rezerwacji pamięci[118].

Wewnątrz nawiasów klamrowych znajduje się lista instrukcji, które zostaną wywołane po uruchomieniu programu[125]. Do przechowywania adresu obiektu określonego typu służą wskaźniki[75]. Dozwolone jest wykonywanie na nich niektórych operacji arytmetycznych. Dowolny wskaźnik można przyrównać do zera (oznaczającego literał pusty, zapisywany też jako NULL)[76]. Porównywanie oraz odejmowanie dwóch wskaźników jest zdefiniowane wyłącznie wtedy, kiedy dotyczą one tej samej tablicy lub – wyłącznie w przypadku porównywania – tego samego obiektu złożonego[77].

Innym rodzajem zmiennych są zmienne statyczne (deklarowane słowem static). Pamięć dla nich inicjalizowana jest w momencie uruchomienia programu i od tego momentu wszystkie odwołania dotyczą tego samego regionu pamięci[108]. W przypadku, gdy zmienną lokalną zadeklarowano jako statyczną, będzie ona przechowywała tę samą wartość pomiędzy różnymi wywołaniami funkcji. Z kolei statyczne zmienne zewnętrzne charakteryzują się linkowaniem wewnętrznym, co oznacza, że nie są widoczne na zewnątrz jednostki tłumaczenia, w której je zadeklarowano[112]. W języku C dostępny jest mechanizm pozwalający na zdefiniowanie synonimów dla istniejących typów danych.

Jego specyfikacja pozwala na rzutowanie typów wskaźnikowych na dowolne inne typy wskaźnikowe. W konsekwencji dowolny region pamięci może być traktowany tak, jakby zawierał dane dowolnego typu. Jednocześnie narzędzia wspomagające pisanie kodu nie są w stanie sprawdzić, czy konwersja typów jest sensowna[164]. W C jest ponadto dozwolone przypisanie wartości do zmiennej innego typu.

Zmienne lokalne, o ile nie użyto żadnego specyfikatora klasy pamięci, są deklarowane jako zmienne automatyczne[41]. Wartości niezainicjalizowanych zmiennych są niezdefiniowane i mogą mieć wartość zależną od kompilatora lub od tego, co akurat było w pamięci[111]. Są one dostępne przez cały czas wykonywania bloku, gdzie zostały zadeklarowane[e].

Komitet ANSI przygotował opis biblioteki standardowej języka C, wymagający dostarczenia programiście odpowiednich funkcji o ściśle określonym działaniu i przeznaczeniu[13]. Pierwsza linijka tego kodu informuje preprocesor, aby dołączył w to miejsce zawartość pliku stdio.h, który wchodzi Analiza techniczna: Metody graficzne w skład biblioteki standardowej języka C[123]. Zadeklarowane w nim są procedury odpowiadające za obsługę wejścia i wyjścia, w tym printf[124]. To od niej rozpoczyna się wykonanie programu napisanego w C. Funkcja ta nie przyjmuje żadnych argumentów i zwraca wartość całkowitą.

Takie pola w trakcie kompilacji są umieszczane w odpowiednio dużej, adresowalnej jednostce pamięci. Jeżeli ma ona wystarczający rozmiar, by pomieścić sąsiednie pola, zostaną one w niej razem upakowane. Standard ISO C nie określa kolejności, w której przylegające do siebie pola bitowe są przechowywane w pamięci[83]. Funkcje w języku C nie mogą być przeciążane[47], ale istnieje mechanizm definiowania funkcji o zmiennej liczbie argumentów[48]. W 2011 roku do języka C wprowadzono także mechanizm definiowania makr generycznych ze względu na typ parametrów oraz wsparcie dla literałów napisowych w standardach Unicode i UTF-8[21]. W 1999 roku do języka C wprowadzono także obsługę tablic o długości ustalanej w czasie działania programu[19].

Składa się ono z listy stałych symbolicznych, każda o wartości będącej liczbą całkowitą. Typy wyliczeniowe funkcjonalnie są równoważne całkowitoliczbowym[69][60]. Dzięki dyrektywie #pragma możliwe jest przekazywanie instrukcji specyficznych dla kompilatora[55][a]. Kompilator C, wraz z kilkoma programami napisanymi w tym języku, został dołączony do drugiej wersji systemu Unix[5]. Latem 1973 jądro tego systemu zostało przepisane w języku C[4].

Dodatkowym ograniczeniem, stawianym przez standard jest to, aby kolejne typy miały zakres niemniejszy od poprzednich. Na przykład obiekt typu short nie może być dłuższy niż int, który z kolei musi być niedłuższy od long[61]. Deklaracja obiektu polega na podaniu typu danych oraz opcjonalnie klasy pamięci i sposobu linkowania, po których występuje przynajmniej jeden identyfikator tworzonego obiektu (lub obiektów)[44]. Program w języku C zapisywany jest w plikach źródłowych, które nie muszą być kompilowane w tym samym czasie.

Do 1980 roku możliwe stało się przekazywanie ich jako parametry funkcji oraz bezpośrednie przypisywanie. Jedynie brak notacji dla literału powodował, że nie były typem pierwszoklasowym. Popularność i szerokie zastosowanie języka C ma bezpośredni wpływ na składnię lub semantykę innych języków programowania[132]. Przede wszystkim najbardziej podobnym i kompatybilnym jest język C++, który powstawał jako rozszerzenie „C z klasami”[148]. W powyższej tabeli zebrano minimalne wymagania stawiane dostępnym w C typom całkowitoliczbowym.

Język C powstawał jako rozwinięcie języka B, wzbogacając się stopniowo o kolejne funkcje. Okresy najszybszego rozwoju języka C to lata 1972–1973 oraz 1977–1979. To czas zdobywania przez niego popularności, czego efektem była dostępność kompilatorów dla praktycznie wszystkich używanych wtedy architektur komputerów i systemów operacyjnych. Zadeklarowanie obiektu ze słowem register sugeruje kompilatorowi, by umieścił go w pamięci o szybkim dostępie (np. rejestrze procesora[112]).