Budowa programu w języku C++

W poprzedniej lekcji udało Ci się napisać oraz przetestować swój pierwszy program w języku C++. Zanim jednak dokładnie wyjaśnimy jak ten program działa, postaramy przedstawić ogólną budowę programu w C++. Wszystkie programy, które będziesz pisać, będą miały identyczną lub bardzo zbliżoną budowę.

Ogólna budowa programu w C++

Mimo, że programy napisane w języku C++ mogą być bardzo różnej długości, wszystkie jednak mają następującą budowę:

# dyrektywy preprocesora

Wszystkie dyrektywy preprocesora poprzedzone są znakiem #. Wszystkie dyrektywy preprocesora są wykonywane przez specjalny program zwany preprocesorem stąd ich nazwa. Na szczęście w większości kompilatorów (o ile nie we wszystkich) nie musimy się martwić tym, że dyrektywy te wykonuje preprocesor. Kompilator automatycznie uruchamia preprocesor gdy wykryje dyrektywę.
Najczęściej wykorzystywaną dyrektywą preprocesora jest dyrektywa include - służy ona do dołączania plików nagłówkowych. Inną popularną dyrektywą jest define - służy ona do tworzenia nazw symbolicznych.

Aby dołączyć jeden ze standardowych plików języka C++ należy napisać:

#include <iostream>

# wykorzystywane przestrzenie nazw

W nieco bardziej skomplikowanych programach, aby ułatwić sobie życie, grupuje się pewne elementy w przestrzenie nazw. Również wszystkie elementy zdefiniowane standardowo w języku C++ są zdefiniowane w przestrzeni nazw - a konkretnie przestrzeni nazw o nazwie std. Aby włączyć dowolną przestrzeń nazw wystarczy napisać:

using namespace nazwa;

gdzie nazwa jest nazwą wybranej przestrzeni nazw.

# funkcje zdefiniowane przez użytkownika

Ponieważ programy pisane w języku C++ mogą być bardzo duże, dlatego też wymyślono mechanizm, aby grupować pewne fragmenty kodu w funkcje. Dzięki temu znacznie łatwiej poruszać się po takim programie czy też pisać programy w kilka osób. Funkcjami zajmiemy się na nieco dalszym etapie nauki.


# główna funkcja programu

Mimo, że funkcja ta działa jak zwykła funkcja ma ona dwie bardzo charakterystyczne cechy. Po pierwsze funkcja ta musi mieć zawsze nazwę main - tak ktoś sobie wymyślił, że główna funkcja programu tak się nazywa i tak już pozostało do dzisiaj. Drugą bardzo charakterystyczną cechą jest to, że od tej funkcji zaczyna się całe wykonanie programu. Najprostsza funkcja main (która nic nie robi), wygląda tak:

int main()
{
  return 0;
}

Jeśli chcemy, aby nasz program cokolwiek wykonał, musimy umieścić dodatkowy kod pomiędzy { oraz return 0;


Dyrektywa include

Jak już wiesz dyrektywa include jest jedną z najczęściej wykorzystywanych dyrektyw preprocesora. Za jej pomocą dołączamy do programu wybrany plik nagłówkowy.


Zastanawiasz się pewnie, po co włączać do programu jakieś pliki nagłówkowe. Otóż w plikach nagłówkowych zdefiniowane są elementy, z których prawie na pewno będziesz chcieć korzystać. Bez kilku czy kilkunastu pliku nagłówkowych napisanie nawet prostego programu byłoby w zasadzie niemożliwe. Niech przykładem będzie to, że aby nawet coś wypisać na ekran (tak jak to miało miejsce w naszym pierwszym programie), należy dołączyć właściwy plik nagłówkowy.


Niestety w początkowym etapie nauki dużym problemem jest jaki plik należy włączyć, aby można było coś zrobić. Otóż co gdzie się znajduje uda Ci się nauczyć, gdy będziesz często korzystać z pewnych elementów. Przydatne mogą być też pliki pomocy dołączone do Twojego kompilatora.


Dyrektywa include występuje w dwóch postaciach:

#include <nazwa>

oraz

#include "nazwa"

W pierwszym przypadku dołączamy plik nagłówkowy, który znajduje się w miejscu określonym przez kompilator. Z takiego dołączania będziemy najczęściej korzystać. W drugim przypadku dołączamy plik znajdujący się w bieżącym katalogu - ta możliwość jest wykorzystywana na nieco wyższym poziomie nauki.


W obu przypadkach nazwa jest nazwą pliku, który chcemy dołączyć do programu. W tym miejscu następuje jednak małe zamieszanie. Wszystkie pliki nagłówkowe mają standardowo rozszerzenie h. Otóż pliki nagłówkowe pochodzące z czystego języka C++ dołączamy podając samą nazwę pliku bez rozszerzenia. Natomiast pliki pochodzące tak naprawdę z poprzednika języka C++, czyli języka C włączamy podając nazwę wraz z rozszerzeniem.
Dla przykładu:

#include <iostream>

ale

#include <stdio.h>

Jednocześnie warto wiedzieć, że niektóre biblioteki języka C mają swoje odpowiedniki w języku C++. Jeśli biblioteka występowała w języku C jako nazwa.h, to w języku C++ powinniśmy spróbować dołączyć ją jako cnazwa - zapisujemy nazwę biblioteki z języka C poprzedzoną literą c bez rozszerzenia. W ten sposób otrzymujemy zamiast stdio.h – cstdio, zamiast math.h – cmath, zamiast string.h - cstring itd. Oczywiście nie wszystkie biblioteki języka C mają swój odpowiednik w C++ - należy wówczas spróbować użyć biblioteki z wersji języka C.


Jeśli będziesz miał problem z którąś z bibliotek w przykładach w tym kursie C++, spróbuj zawsze dołączyć plik za pomocą drugiej metody – jeśli wykorzystana jest biblioteka C++ spróbuj wersji z języka C, a jeśli dołączona jest biblioteka C, spróbuj dołączyć wersję z C++. Warto zawsze skorzystać z tej rady zanim zdecydujesz się na zmianę kompilatora lub zanim zaczniesz szukać przyczyny tego problemu (np. brak biblioteki w systemie).


Mimo, że na razie z tego i tak nie będziesz korzystać, to warto dodać, że wykorzystując drugą metodę dołączania plików nagłówkowych, z wykorzystaniem ", musimy dodać rozszerzenie pliku (niekoniecznie h) oraz, że możemy dołączać pliki znajdujące się nie tylko w bieżącym katalogu.
Na przykład:

#include "krzysiek/moj.hpp"

spowoduje dołączenie pliku o nazwie moj.hpp znajdującego się w katalogu krzysiek, przy czym katalog krzysiek znajduje się w bieżącym katalogu.


Wykorzystywane przestrzenie nazw

Jak już wspomniałem, przestrzenie nazw ułatwiają grupowanie pewnych elementów. Wszystkie standardowe elementy języka są umieszczone w przestrzeni nazw std. Dlatego też warto zadeklarować, że chcemy wykorzystywać tę przestrzeń nazw:

using namespace std;

Mimo, że możemy wykorzystać tą metodę, wcale nie musimy. Jednak deklarując wykorzystywanie jakiejś przestrzeni nazw, ułatwiamy sobie znacznie zapis w dalszej części programu. Dlatego mimo pewnych niekorzystnych skutków takiego działania uważam, że warto zawsze dołączać na początku programu standardową przestrzeń nazw std.


Można też zrezygnować z deklaracji użycia przestrzeni nazw. Wtedy jednak w programie, który przedstawiłem Ci w pierwszej lekcji, należałoby wszędzie zamiast cout napisać std::cout oraz wszędzie zamiast cin napisać std::cin. Mam nadzieję, że w ten sposób przekonałem Cię, że jednak warto skorzystać z polecanej przeze mnie pierwszej metody, bowiem znacznie skraca to nam pisanie.


UWAGA: Jeśli zapomnisz włączyć standardową przestrzeń nazw std, nie zdziw się, jeśli kompilator będzie wypisywać bardzo dziwne błędy. Czasami zorientowanie się, skąd się wziął błąd może zająć znacznie więcej czasu niż pisanie samego programu. Dlatego radzę Ci dobrze - nie zapominaj o dołączaniu przestrzeni nazw std!


Główna funkcja programu

Mimo, że w programie możemy mieć wiele różnych funkcji, zawsze musimy umieścić główną funkcję o nazwie main. Jest to jedyna funkcja, która jest uruchamiana automatycznie. Wszystkie pozostałe funkcje musimy uruchomić sami.


Wiesz już jak wygląda funkcja main i wiesz, że aby program coś wykonywał, to coś musi się znajdować właśnie w funkcji main. Na razie nie będę tłumaczył do czego służą tajemnicze int oraz (). W nawiasach klamrowych umieszczamy właściwą treść funkcji, czyli treść naszego programu.


Warto zwrócić uwagę na tajemniczą linię:

  return 0;

Otóż ta tajemnicza linia, umieszczona przed nawiasem kończącym treść funkcji, czyli przed } zwraca wartość wywołania naszego całego programu. Wartość taka jest wykorzystywana przez system operacyjny do stwierdzenia, czy program zadziałał poprawnie, a jeśli nie, to co spowodowało błąd.


Przyjęło się, że poprawne działanie programu jest sygnalizowane zwróceniem wartości 0, dlatego też taką wartość będziemy zwracać. Ponieważ w tym kursie będziemy pisać proste programy, dlatego też możesz przyjąć, że w funkcji main należy zawsze zwracać wartość 0. Mimo, że niektóre kompilatory nie sygnalizują błędu, jeśli ta linia zostanie pominięta, jest to linia dosyć ważna i lepiej o niej nie zapominać, zwłaszcza jeśli byśmy chcieli pisać programy, które ktoś w przyszłości będzie wykorzystywać.

Podsumowanie

A zatem najważniejsze jest, żeby wszystko robić z głową. To co w jednym programie jest niezbędne, w innym będzie zbędnym dodatkiem, który tylko niekorzystnie wpłynie na szybkość działania programu. Dla pełnego zobrazowania zagadnienia, poniżej przedstawiam jeszcze 3 przykłady typowych schematów kodu.


int main()
{
  return 0;
}
program nr 2.1

Powyższy program to najprostszy program. Składa się on tylko z funkcji main, wewnątrz której nic nie robimy, czyli sam program faktycznie też nic nie robi. Ponieważ program nic nie robi, nie musimy dołączać ani żadnego pliku nagłówkowego ani standardowej przestrzeni nazw std.


Schemat prostego programu

#include <iostream>

using namespace std;

int main()
{
  return 0;
}
program nr 2.2

To jest schemat kodu programu, jaki my zazwyczaj będziemy wykorzystywać. Oczywiście w funkcji main będziemy umieszczać dodatkowe instrukcje.

Schemat złożonego programu

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
  return 0;
}
program nr 2.3

Tak naprawdę ten schemat wcale nie jest złożony. Różni się on jedynie od poprzedniego tym, że oprócz pliku nagłówkowego iostream, dołączamy dodatkowo plik nagłówkowy string. Czasami bowiem będzie zdarzać się, że będziemy musieli dołączyć dwa (tak jak tutaj) lub większą ilość plików nagłówkowych, aby w sposób wygodny i szybki napisać program.


Plik nagłówkowy cstring jest plikiem właściwym dla języka C++ do obsługi napisów. W niektórych kompilatorach zamiast pliku cstring należy dołączyć plik string. Jeśli również dołączenie pliku string nie pomaga, można wówczas spróbować dołączyć plik string.h
Najbardziej właściwe jednak dla języka C++ jest używanie pliku nagłówkowego cstring, który jest zgodny ze standardami języka C++, zatem jeśli Twój kompilator umożliwia dołączenie pliku cstring, to jego powinieneś używać.


powrót