Struktura programu W programach napisanych w C++ litery wielkie i małe są rozróżniane i często po nauce Pascala są przyczyną błędów. Program napisany w języku C++ składa się zazw yczaj z następujących części: dyrektyw preprocesora,- opcjonalne deklaracji i definicji globalnych struktur danych i danych, - opcjonalne deklaracji i definicji funkcji, - opcjonalne definicji funkcji main. Widzimy, że w każdym programie musi być definicja funkcji main i wykonywanie programu rozpoczyna się zawsze od początku bloku występującego w definicji tej funkcji. Definicje innych funkcji zazw yczaj poprzedzają definicję funkcji main, ale mogą również występować po main o ile przed main znajdą się ich deklaracje (zapowiedzi). Przykład programu w C++Borland: /* program przykładowy */ #include <iostream> using namespace std; void main() { cout << Pierwsza linia\n << Druga linia ; system( pause ); } // koniec programu Na ekranie monitora zostaną wyświetlone w dwu liniach teksty Pierwsza linia Druga linia Preprocesor Program w języku C++ składa się z jednego lub kilku plików. Pojedynczy plik 1
z kodem w C++ tłumaczony jest (podobnie jak w kompilatorach języka C) w kilku fazach. Wstępnego przetworzenia programu źródłowego zapisanego w C++ dokonuje preprocesor. Przetwarzanie to sterowane jest dyrektywami, z których każda rozpoczyna się od znaku #. Działanie niektórych dyrektyw może być zastąpione odpowiednimi konstrukcjami języka C++. Każda linia rozpoczynająca się do # uważana bywa za dyrektywę preprocesora. Dyrektyw y występują zazw yczaj na początku pliku zawierającego tekst źródłowy, ale można umieszczać je i w innych miejscach. Niektóre dyrektywy #include pozwala na dołączenie do programu pliku określonego argumentem tej dyrektyw y. Nazwa dołączonego pliku (lub ścieżka dostępu) powinna być ujęta w nawias y < >, gdy poszukiwanie wskazanego pliku ma odbyć się w katalogu standardow ym INCLUDE (lub pod wskazanym adresem), albo w cudzysłow y, gdy poszukiwanie ma rozpocząć się od katalogu bieżącego. #include <iostream> #include funkcje.cpp Pojedyncza dyrektywa #include umożliwia dołączenie jednego pliku. Przy pomocy tej dyrektyw y dołączamy pliki nagłówkowe. W pow yższym programie przykładow ym mamy dołączony plik nagłówkow y iostream zawierający odpowiednie deklaracje do obsługi we/wy. Pewne cechy języka zależą od konkretnej implementacji kompilatora. Są to np: typ operatora sizeof oraz zakres y wartości standardowych typów danych. Informacje te są zdefiniowane w standardowych plikach nagłówkow ych - header'ach, w których zdefiniowane są również standardowe funkcje biblioteczne: <float> <limits> <stddef> <new> <stdarg> <stdlib> Z wyjątkiem pliku <new> (specyficznego dla C++) wszystkie należą do standardu ANSI C. W dołączanych plikach mogą również znajdować się dyrektyw y #include. #define powoduje zastąpienie w dalszej części programu identyfikatora będącego pierwszym argumentem przez tekst będący jej drugim argumentem. 2
Tak na przykład dyrektywa #define Rozmiar 150 spowoduje zastąpienie wszystkich wystąpień identyfikatora Rozmiar (znajdującego się za tą dyrektywą) przez tekst 150. W pewnym zakresie dyrektywa ta umożliwia definiowanie stałych. Tekst zastępujący może składać się z wielu słów np. #define NowaCena Cena*(1+NarzutProcentowy/100) Tekst zastępujący może również zawierać dyrektyw y #define. Zagnieżdżenie nie może jednak powodować rekurencji. Wprowadzoną definicję wiążącą identyfikator i tekst zastępujący można odwołać za pomocą dyrektyw y #undef, np. #undef NowaCena. Za pomocą dyrektyw #if, #elif, #else, #endif można sterować procesem kompilacji, wskazując, które z plików źródłowych będą dołączane i jakie modyfikacje tekstowe będą w nich dokonywane. Funkcja main Każdy program napisany w języku C++ musi zawierać definicje funkcji main. Wykonanie programu rozpoczyna się od początku bloku definiującego tę funkcję, a zakończenie wykonywania po osiągnięciu końca bloku lub po napotkaniu instrukcji return. Funkcja main najczęściej nie oblicza wyniku i jest bezargumentowa. Blok w C++ zaznaczamy poprzez ujęcie tekstu w nawiasy klamrowe {...}. Nawias y te można interpretować jako początek i koniec bloku (czy instrukcji złożonej)- czyli prawie pascalowe begin i end {różnica bo deklaracje zmiennych}. Komentarze Komentarze ujmujemy w parę /*... */ lub // i do końca linii to jest komentarz. Standardowo kompilatory nie pozwalają na zagnieżdżanie komentarzy. 3
Alfabet, przy pomocy którego zapisujemy tekst algorytmów w C++ jest taki sam jak w Pascalu. Do liter zaliczana jest zazwyczaj kreska podkreślająca _. Identyfikatory tworzymy z liter i cyfr, rozpoczynając od litery (lub znaku podkreślenia). W definicji nie ma ograniczenia na długość identyfikatora. Zazwyczaj poszczególne implementacje języka C++ rozróżniają nazwy do 31 lub 32 znaków tzn. jeśli dwa napisy przedstawiające identyfikatory różnią się na 33 pozycji to przedstawiają na ogół ten sam identyfikator. Przypominamy, że duże i małe litery są rozróżnialne. Dodatkowo identyfikatory zawierające podwójny znak _ czyli są zarezerwowane do użycia przez implementacje C++ i przez standardowe biblioteki. Dlatego nie powinny być stosowane przez użytkowników. Podobnie identyfikatory rozpoczynające się od znaku _ nie powinny być stosowane przez użytkowników (zwykłych użytkowników), gdyż są rezerwowane przez implementacje C. Słowa kluczowe C i C++ auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while słowa kluczowe tylko C++ asm bool catch class const_cast delete dynamic_cast false friend inline new operator private protected public template this throw true try typeid typename using virtual wchar_t reinterpret_cast static_cast Słowa kluczowe są słowami zastrzeżonymi i nie mogą być używane przez programistę w innym celu aniżeli są przeznaczone. W przypadku ich użycia 4
kompilator powinien wykazać wystąpienie błędu. Mogą być jeszcze inne słowa zastrzeżone w zależności od realizacji C++, jak również niektóre z powyższych mogą nie wystąpić (np. bool w BC4.52). Typy danych liczbowych Język C++ zawiera pewną liczbę typów danych zdefiniowanych pierwotnie, dzięki którym można przedstawiać liczby całkowite, rzeczywiste i znaki. Typ Długość Zakres unsigned char 8 bits 0.. 255 char 8 bits -128.. 127 short int 16 bits -32,768.. 32,767 unsigned int 32 bits 0.. 4,294,967,295 int 32 bits -2,147,483,648.. 2,147,483,647 unsigned long 32 bits 0.. 4,294,967,295 long 32 bits -2,147,483,648.. 2,147,483,647 enum 16 bits -2,147,483,648.. 2,147,483,647 float 32 bits 3.4 x 10-3 8.. 3.4 x 10 + 3 8 double 64 bits 1.7 x 10-3 0 8.. 1.7 x 10 + 3 0 8 long double 80 bits 3.4 x 10-4 9 3 2.. 1.1 x 10 + 4 9 3 2 Do przedstawiania liczb całkowitych korzystamy z typów char, short, int i long. Typy całkowite są ze znakiem lub bez znaku. Do przedstawiania liczb rzeczywistych mamy do dyspozycji typy float, double i long double. Zdarza się, że typy double i long double są identyczne. Wartości stałe Literałami, czyli dosłownie stałymi, nazywamy pojawiające się w tekście programu dane zapisane w sposób dosłowny. Z każdym literałem związany jest typ. Literały są nieadresowalne. Literały całkowite: można zapisać w systemie dziesiętnym (tradycyjny zapis), ósemkow ym (zapis zaczynamy cyfrą 0 zero) lub w szesnastkow ym (zapis rozpoczynamy 0x lub 0X zero iks): 5
20 //dziesiętnie 024 //ósemkowo 0x14 //szesnastkowo Domyślnym typem literałów całkowitych jest typ int ze znakiem. Jeśli stałą całkowitą zakończymy literą L lub l to literał będzie należał do typu long. Podobnie zapisuje się literał typu unsigned, kończąc literą U lub u. Np. 128u 1034L 1348UL 124Lu Literały zmiennopozycyjne zapisujemy albo w postaci w ykładniczej z literką E lub e albo jako zwyczajny ułamek. Domyślnym typem jest typ double. Aby otrzymać literał należący do typu float należy na końcu literału dopisać literkę F lub f. Aby otrzymać literał typu long double na końcu literału trzeba dopisać L lub l. Przykłady literałów zmiennopozycyjnych: 3.14f 0.3F 45.7L 2e-10L 2.e-1.2e-10F.0 Nie są poprawnymi literałami -10F (brak przynajmniej kropki) E10 (brak mantys y). Ale jest przyjmowane bez błędu -2U co daje jako stałą 65534. Literały znakow e zapisuje się ujmując znak w pojedynczy cydzysłów: a 2 W pamięci przechowywane są jako liczby całkowite typu char. Zamiast znaku widocznego możemy również skorzystać z opisu znaku, rozpoczynającego się od backslasha po którym podajemy kod ASCII znaku będący liczbą ósemkową lub szesnastkową w postaci \***, gdzie *** oznacza zapis przy użyciu co najw yżej trzech cyfr liczby ósemkowej (zero wiodące można lub należy pominąć) lub liczby szesnastkowej (można zacząć od x): '\107' '\x47' opisują tą sama stałą a mianowicie literę G. Można posługiwać się znakami sterującymi: \n nowy wiersz \t pozioma tabulacja 6
\v pionowa tabulacja \b cofnięcie (backspace) \r do początku wiersza \f nowa strona \\ backslash \? znak? \ apostrof \ cudzysłów Uwaga. Na ogół brak sygnalizacji dla błędnego zapisu stałej znakowej np. cout << z1 ; powoduje w yświetlenie pewnej liczby. Łańcuchy (literały napisow e) składają się z ciągu znaków ujętego w podwójny cudzysłów W przypadku gdy tekst nie mieści się w jednym wierszu, to na końcu takiego wiersza należy postawić \ (bachslash) i w następnym kontynuować tekst (od początku linii bo wchodzą spacje). W łańcuchu mogą występować znaki sterujące i opis y znaków. Typem tych danych jest tablica znaków, która zawiera sam literał jak i znak pusty (null), dodany przez kompilator jako ostatni jej element. Zatem jest różnica między A (jeden znak) a A ( dwa znaki). Zmienna Do ustalenia tożsamości zmiennej służy jej nazwa, nadawana jej przez programistę. Każda zmienna musi mieć określony typ, który podawany jest poprzez odpowiedni specyfikator typu jak: char, short, int, long, float czy double. Ze zmienną związana jest definicja zmiennej i deklaracja zmiennej. Definicja zmiennej służy do zarezerwowania dla tej zmiennej obszaru pamięci, wprowadzenia jej nazwy i określenia typu. Dopuszcza się rozszerzenie definicji o nadanie zmiennej jej wartości początkowej. Nie można w programie definiować tej samej zmiennej więcej niż jeden raz. Deklaracja zmiennej służy do oznajmienia, że zmienna taka istnieje i została 7
zdefiniowana w innym miejscu programu. Deklaracja składa się ze specyfikatora typu oraz z nazw y zmiennej, poprzedzonych słowem kluczowym extern. Deklaracja nie jest definicją i nie służy do rezerwacji miejsca pamięci. Tą samą zmienną można deklarować wielokrotnie w programie. Definicja zmiennej Najprostsza definicja zmiennej składa się ze specyfikatora typu i nazw y. Definicje należy zakończyć średnikiem. Po specyfikatorze może w ystąpić lista zmiennych oddzielonych od siebie przecinkami. Zmienne mogą mieć wartości początkowe. Przykłady: int dzien, miesiac, rok; unsigneg long odleglosc; double zarobki, oplaty; double cena = 102.2; // nadawanie wartości początkowej int marza(5);// drugi sposób marza=5; double koszt(cena*marza); /* wartość początkowa poprzez wyrażenie */ Stałe Stałą nazywamy identyfikator związany z wartością nie ulegającą zmianie podaczas w ykonywania programu. Definicja rozpoczyna się od słowa kluczowego const, po czym podajemy typ stałej, nazwę i po znaku = wartość. const int DniTygodnia=7, TygodniWRoku=52; const double pi=3.141592,e=2.7182; Operator przypisania to w C++ znak =. 8