Ogólna struktura programu w języku C

Słownik pojęć

Poniższy słownik wyjaśnia znaczenie pojęć używanych na tej stronie i w jej kontekście

Proces 'tłumaczenia' kodu źródłowego na program wykonywalny

Proces tłumaczenia kodu źródłowego na kod maszynowy
Rys. 1. Proces tłumaczenia kodu źródłowego na kod maszynowy

Na rysunku 1 przedstawiony jest schematycznie przebieg procesu tłumaczenia kodu źródłowego programu napisanego w języku C lub C++ na plik wykonywalny w formacie binarnym, zależnym od systemu operacyjnego (lub platformy sprzętowej), w którym ma być uruchomiony.

W pierwszym etapie analizę kodu źródłowego wykonuje program, zwany preprocesorem. Często jest tak, że kompilator spełnia jednocześnie rolę preprocesora, a więc jeszcze przed etapem kompilacji sam wykonuje etap preprocessingu.

Preprocessing polega na tym, że kod źródłowy analizowany jest pod kątem występujących w nim dyrektyw preprocesora. Dyrektywy te są po prostu rozkazami, które rozpoznaje i wykonuje tylko preprocesor.

Przykłady takich dyrektyw, to:

Po etapie preprocessingu mamy więc nasz kod źródłowy, ewentualnie uzupełniony o włączone do niego pliki nagłówkowe, zawierające deklaracje używanych funkcji, typów, itp.
Taki plik analizowany jest następnie przez kompilator. Kompilator sprawdza poprawność kodu źródłowego, i jeżeli nie wystąpią błędy, tworzy plik binarny, np. z rozszerzeniem o lub obj.

Po etapie kompilacji następuje etap konsolidacji, w którym pliki binarne, powstałe po kompilacji kodu źródłowego, łączone są z plikami binarnymi bibliotek: własnych, dostarczonych wraz z kompilatorem, lub innych.
W wyniku tego (o ile nie wystąpiły błędy konsolidacji) otrzymujemy plik wykonywalny w formacie gotowym do uruchomienia w bieżącym systemie operacyjnym.

Z przedstawionego opisu wynika, że proces tłumaczenia kodu źródłowego na program jest dość złożony. Nie należy się jednak, szczególnie na początku nauki programowania w C/C++, tym martwić. W praktyce najczęściej jest tak, że etap preprocessingu przebiega w sposób niezauważalny dla programisty (o ile nie popełnił błędu związanego z wykorzystaniem dyrektyw), a dwa następne etapy - kompilacja i konsolidacja, wykonywane są automatycznie jeden po drugim.

Omówienie ogólnej struktury programu

Oto przykład prostego programu w języku C:

Ogólna struktura programu w języku C/C++

Dyrektywy preprocesora

Dyrektywy preprocesora rozpoczynają się znakiem # i mogą wystąpić w prawie dowolnym miejscu kodu źródłowego. Dyrektywy #include, których początkujący programista najczęściej używa, występują jednak z reguły na początku pliku - tak jak w przedstawionym przykładzie.

Obszar deklaracji i/lub definicji

Obszar ten, zaznaczony w przykładzie, jest wygodnym miejscem na deklarowanie lub definiowanie własnych funkcji, typów danych, lub zmiennych globalnych. Tych ostatnich należy jednak bardzo unikać, ze względu na możliwość wystąpienia późniejszych trudności przy wykorzystaniu pisanego programu jako części innego.
Możliwe jest również umieszczanie definicji za funkcją main, jednakże wtedy definiowane funkcje muszą być zadeklarowane przed miejscem ich użycia, czyli np. przed funkcją main.

Nagłówek funkcji main

Definiuje funkcję o nazwie 'main'. Nazwa ta jest zastrzeżona, ponieważ funkcja main jest tożsama z programem, jako takim, i wywoływana jest przez system operacyjny, w chwili uruchomienia naszego skompilowanego programu. Możliwe są inne definicje nagłówka - tu przedstawiona została najbardziej podstawowa.

Początek i koniec instrukcji złożonej

Nawiasy { oraz } oznaczają odpowiednio początek i koniec tzw. instrukcji złożonej. Instrukcja złożona stanowi blok instrukcji, objęty właśnie tymi nawiasami. Przy definiowaniu jakiejkolwiek funkcji (nie tylko main) pierwszym widocznym znakiem, jaki musi wystąpić po nagłówku funkcji, jest właśnie nawias {. Widoczny znak, to znak inny, niż spacja, tabulator, czy znak końca linii.

Instrukcje

Instrukcje proste, to instrukcje nie będące instrukcjami złożonymi - patrz wyżej. W naszym przykładzie występują dwie instrukcje proste:
printf("Czesc!\n");
oraz
return 0;
Pierwsza z nich powoduje wypisanie na konsoli tekstowej programu tekstu, który znajduje się w cudzysłowach, druga natomiast powoduje zakończenie działania funkcji main (czyli, jak już wiemy, naszego programu), ze zwróceniem do systemu operacyjnego kodu powrotu o wartości 0.
Widać, że każda instrukcja prosta musi być zakończona średnikiem ;