Język programowania C/C++ | ||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||
Ogólna budowa programu#include < > <= dyrektywa (instrukcja) preprocesora, dołą-czenie biblioteki lub pliku nagłówkowego. #include < iostream.h > // <= jeden ze standardowych plików nagłówkowych. main () { cout << "C++"; // "<<" - wejście, ">>" - wyjście. return 0;//<= informacja dla systemy operacyjnego //o poprawnym zakończeniu programu. } W przykładzie chcemy, aby program wyświetlał określony komunikat. W C++ nie ma standardowych instrukcji Wejścia / Wyjścia. Jeżeli program ma wyświetlać lub pobrać dany komunikat to musi posłużyć się specjalnych funkcji. Funkcje te znajdują się w standardowych bibliotekach Wejścia / Wyjścia, dołączonych razem z kompilatorem języka, aby można było jej użyć, trzeba kompilatorowi dostarczyć pewnych informacji, umieszczonych w specjalnym pliku określanym mianem pliku nagłówkowego (*.h - ang. header). Dla biblioteki funkcji Wejścia / Wyjścia jest to plik "iostream.h", podzielony na dwie klasy istream i ostream. Włączanie tego pliku odbywa się za pomocą dyrektywy #include. Do tekstu można włączyć pewne znaki, które mają specjalne znaczenie:
Stałe i ZmienneStała może być liczbą, pojedynczym znakiem lub tekstem. Zmienna jest nazwą, pod którą mogą być podstawione różne wartości. Zarówno stałą jak i zmienną jest związany jej typ: char - typ znakowy, int - typ całkowity, float - typ rzeczywisty, double - typ zmiennoprzecinkowy (rzeczywisty) o podwójnej precyzji, enum - typ wyliczeniowy (to typy podstawowe). Niektóre z typów mogą być dodatkowo modyfikowane za pomocą kwali-fikatorów short (krótki), long (długi), signed (ze znakiem), unsigned (bez znaku, dodatnie) Są jeszcze inne typy: near (bliski), far (daleki). Istnieje jeszcze jeden szczególny typ void, (nieistniejący, pusty). Możliwe jest deklarowanie wskaźników na ten typ np. void a (void *a) co powoduje, że staje się on wskaźnikiem uniwersalnym niekiedy zwanym wskaźnikiem adresowym, któremu można przypisać wskaźniki na dowolne typy, odwrotne stwierdzenie jest dla C++ nieprawdziwe. Przypisanie wskaźnika na typ void wskaźnikowi na inny typ zawsze wymaga jawnego użycia operatora konwersji. Słowo kluczowe void można rozumieć jako brak wartości (zero, nic), ma ono kilka charakterystycznych znaczeń:
Na wskaźnikach na typ void, nie można wykonywać żadnych operacji arytmetycznych ale można je porównywać ze sobą i z zerem. Ta ostatnia własność jest bardzo ważna w zaawansowanych programach, kiedy trze-ba np. stwierdzić czy jakiś wskaźnik wskazuje ten sam obiekt, niezależnie od tego jakiego typu może być ten obiekt. Stałe całkowite - są przykładami literałów stałych. Literałów, dlatego, że mówimy jedynie o ich wartościach stałych, ponieważ ich wartości nie możemy zmieniać. Typ stałej całkowitej przyjmowany domyślnie przez kompilator, zależy od jej postaci, wartości i przyrostka. Jeżeli jest to liczba dziesiętna i nie ma przyrostka to typ domyślny zależy od jej wartości i jest typem int, long int, unsigned long int. Jeżeli jest to liczba oktanalna lub szesnastkowa (heksadecymalna) i nie ma przedrostka, to typ domyślny zależy od jej wartości i jest typem int, unsigned int, long int bądź unsigned long int. Dodając specyfikator u lub U (unsigned) i/lub l lub L (long) możemy wymusić inny sposób reprezentacji stałej całkowitej. Stałe zmiennopozycyjne - należą do podzbioru liczb rzeczywistych, można je zapisywać w notacji dziesiętnej z kropką dziesiętną np. 0.0, .2, 2. , -84.21 lub w notacji wykładniczej np. 1.11e12, -3.14159E-13. Jeżeli po liczbie nie podano specyfikatora typu, to kompilator nadaje jej typ domyślny double. Dokładność stałej zmiennopozycyjnej można wymusić dodając po zapisie liczby modyfikatora f lub F (float) i/lub l lub L (long double) np. -84.11f, .234L, 1.0L. Stałe znakowe - stała (literał) znakowa jest to ciąg złożony z jednego lub większej liczby znaków ujęty w pojedyncze apostrofy np. 'A'. Stałe znakowe są typu char. Wartością stałej jednoznakowej jest wartość numeryczna znaku w maszynowym kodzie znaków np. dla zbioru znaków ASCII wartością A jest 65 (dziesiętne), zaś typem stałej wieloznakowej jest typ int. Deklaracje zmiennychSkładnia: Typ nazwa_zmiennej_tego_typu ; #include Zmienna jest widoczna tylko wewnątrz bloku, w którym została zade-klarowana. Wynika z tego, że w jednym programie możemy bez problemu użyć dowolnej liczby zmiennych o tej samej nazwie, pod warunkiem, że nie będą się one znajdować wewnątrz tego samego bloku, modułu lub instrukcji grupującej. int a = 1 ; cout << a << " " ; // <= spacja { int a = 10 ; cout << a << "\n" ; { int a = 100 ; cout << a ; } } Deklarowanie stałychSkładnia: const typ_zmiennej nazwa_zmiennej = wartość ; Jeżeli deklarację int a = 7 ; poprzedzimy słowem kluczowym const to przekształcimy symboliczną zmienną a w stałą symboliczną o tej samej nazwie. Wartość tak zdefiniowanej stałej symbolicznej pozostaje niezmienna w programie, a każda próba zmiany tej wartości będzie sygnalizowana jako błąd. Słowo kluczowe const, które zmienia interpretację definiowanej wielkości nazywany jest modyfikatorem typu. ! Stała symboliczna po zdefiniowaniu musi być zainicjowana ! np. zapis const double e ; jest błędny ponieważ e nie zostało za-inicjowane. W przypadku stałych znakowych istnieją dwa bardzo wygodne, równo-ważne sposoby ich definiowania: const char LITERA = 'A'; const char LITERA = '0x41'; oba zapisy deklarują stałą znakową będącą literą 'A' ma ona kod ASCII dziesiętny 65, szesnastkowy 41. Stałe są widoczne tylko w pliku źródłowym, w którym zostały zadekla-rowane. Arytmetyczne operatory przypisania
Operatory inkrementacji i dekrementacjiC++ umożliwia dostęp do specjalnych operatorów inkrementacji czyli zwiększania i dekrementacji czyli zmniejszania. W zapisie wygląda to '++', '--'. Operatory te umożliwiają zwiększanie i zmniejszanie o jeden wartości przechowywanej w zmiennej. Operatory inkrementacji:
Operatory dekrementacji:
Przykład: int i, j, k, = 5 ; k++ ; // k ma wartość 6, tu taki sam efekt jak ++k --k ; // k ma wartość 5, tu taki sam efekt jak k- k = 5 ; i = 4 * k++ ; // k = 6, i = 20 k = 5 ; j = 4 * ++k ; // k = 6, j = 24 Funkcje znakowego wejścia i wyjściaFunkcje te znajdują się w pliku nagłówkowym
funkcje znakowego wyjścia:
Funkcje putchar () i getchar () działają z urządzeniami wejścia wyjścia w ogólności (konsola, porty COM, drukarki) Przykład: char a, b, c ; cout << "Podaj pierwszy znak" ; a = getche () ; cout << "\n Podaj drugi znak" ; b = getch () ; putch (b) ; cout << "\n Podaj trzeci znak" ; c = getch () ; put (c) ; cout << "\n\n Podales znaki " ; putch (a) ; putch (b) ; putch (c) ; Sterowanie ekranem
Operatory relacji Sterowanie kursorem
Przykład: char c = ' ' ; //spacja clrscr () ; while (c != 'g') { if (wherex () >= 79) gotoxy (1, wherey ()) ; if (wherey () >= 24) gotoxy (wherex (), 1); putch ('O') ; c = getch () ; gotoxy (wherex () -1, wherey ()) ; putch (' ') ; ď spacja } Decyzje C++Składnia if: if (warunek) instrukcja ; np. double x ; clrscr () ; cout << "Podaj liczbe" ; cin >> x ; // funkcja sqrt () w pliku Składnia if else : if (warunek) instrukcja1 ; else in-strukcja2 ; Przykład: char c ; clrscr () ; cout << "Podaj liczbe" ; cin >> c ; c = toupper (c) ; // zamiana małych liter na duże if (c == 'A' || c == 'I' || c == 'O' || c == 'E' || c == 'U' || c == 'Y') cout << "wprowadzona litera jest samogłoska" ; else cout << "wprowadzona litera nie jest samogłoska" ; Wielokrotna instrukcja if...else...Zagnieżdżona instrukcja if...else... wykonuje serię testów aż wystąpi jedna z poniższych sytuacji:
Przykład: char c ; clrscr () ; cout << "Podaj znak" ; cin >> c ; if (c >= 'A' && c <= 'Z') cout << "litera duza\n" ; else if (c >= 'a' && c <= 'z') cout << "litera mala\n" ; else if (c >= '0' && c <= '9') cout << "cyfra/n" ; else cout << "inny znak\n" ; Instrukcja wyboru switch ()
Przykład: char c ; clrscr () ; cout << "Podaj znak" ; cin >> c ; switch (c) { case "A": case "B": . . . cout << "Duza litera" ; break ; case "a": case "b": . . . cout << "Mala litera" ; case "0": case "1": . . . cout << "Cyfra" ; break ; default : cout << "Inny znak" ; } Pętlefor, pętla ta w C ma bardzo rozpowszechnione zastosowanie może obsługiwać zarówno stałe jak i warunkowe iteracje. Składnia: for ( Przykład: for (i = 0 ; i < 10 ; i++) cout << "kwadrat z " << i << " = " << i * i << '\n' ; for (;;) // pętla otwarta Instrukcja pętli for zawiera trzy elementy, ale są one opcjonalne. Pierwszy element inicjuje zmienną sterującą pętli. Druga część pętli jest warunkiem, który określa czy pętla będzie wykonywać kolejne iteracje. Ostatnia część pętli for jest instrukcją zwiększającą lub zmniejszającą zmienne sterujące pętli, takie zmienne istnieją tylko w obrębie tej pętli. Przykład: { double a = 10 ; int n ; cout << "Podaj liczbe z zakresu [1..30]: " ; cin << n ; if (n > 0 && n <= 30) { for (int i = 1 ; i <= n ; i++) a += (double)i ; cout << n << " != " << a << '\n' ; } else cout << "Liczba z poza zakresu" ; return 0 ; } Pętla deklaruje zmienną sterującą pętli i. Pętla wykorzystuje tę zmienną do uaktualnienia wartości przechowywanej zmiennej a. Pętla inicjuje zmienną sterującą pętli przypisując jej wartość 1. Testem pętli jest wyrażenie i <= n. Instrukcją inkrementującą pętli jest i++ co zwiększa zmienną sterującą pętli o jeden. Inne sposoby zapisu tej pętli:
Modyfikacja programu: { double a = 10 ; int n, i = 1 ; cout << "Podaj liczbę z zakresu [1..30]: " ; cin >> n ; if (n > 0 && n <= 30) { for (; i <= n ;) a *= (double) i++ ; cout << n << " != " << a << '\n' ; } else cout << "Liczba z poza przedziału" ; return 0 ; } Program jest tak zmodyfikowany, że pętla korzysta tylko z testu pętli (drugiego elementu) pozostałe elementy zmienna sterująca pętli i jest zadeklarowana razem z innymi zmiennymi lokalnymi w funkcji main. Zmienna i jest inicjowana wartością 1 w konsekwencji pętla for nie musi deklarować ani inicjować zmiennej sterującej pętli. Jeżeli chodzi o inkrementację tej zmiennej operator inkrementacji jest używany w instrukcji uaktualniającej wartość silni (a) to podejście zwalnia pętlę for z samodzielnego inkrementowania zmiennej sterującej. Operator warunkowy ?:Jest to jedyny operator trójargumentowy w C++. Składnia: Wartość tak utworzonego wyrażenia jest obliczana następująco, najpierw wartościowane jest wyrażenie1, jeżeli jest to wartość niezerowa (prawda) to wartościowane jest wyrażenie2 i wynikiem obliczeń jest jego wartość przy zerowej wartości wyrażenia (wyrażenie 1 - fałsz) wynikiem obliczeń będzie wartość wyrażenia3. Przykład: int a, b, z ; cin >> a >> b ; z = (a > b) ? a : b ; // z == max (a, b) cout << z << endl ; <= opróżnia bufor wyjściowy return 0 ; Rzutowanie czyli konwersja typówW języku C++ normą jest niż wyjątkiem tzw. arytmetyka mieszana, to jest sytuacja gdy w instrukcjach i wyrażeniach arytmetycznych argumenty operatorów są np. różnych typów. Możemy np. dodawać wartości wyrażeń typu int do wyrażeń typu long, wartość typu float do wartości typu double itd. W takich przypadkach argumenty każdego operatora muszą zostać przekształcone do jednego, tego samego typu dopuszczalnego dla danego operatora. Operacja ta nazywa się rzutowaniem lub konwersją. Konwersja może być niejawna, wykonywana automatycznie przez kompi-lator bez udziału programisty. Język C++ programiście dokonać także konwersji jawnych oferując mu odpowiednie operatory konwersji. Zarówno konwersja jawna jak i niejawna muszą być bezpieczne tzn. takie, aby w wyniku konwersji nie była tracona żadna informacja. Jest pewne, że jeśli liczba bitów maszynowej reprezentacji wielkości podlegającej konwersji nie ulega zmianie bądź wzrasta po konwersji to taka konwersja jest bezpieczna. Bezpieczna konwersja argumentu węższego (mniej bitów) do szerszego typu nazywana jest promocją typu. Typowym przykładem promocji jest automatyczna konwersja typu char do int. Powód, wszystkie predefiniowane operacje na literałach i zmiennych typu char są faktycznie wykonywane na liczbach porządkowych znaków pobieranych ze zbioru kodów maszynowych (tj. ASCII). Powyższe dotyczy także typu short i enum. Podane zestawienie typów od najwęższego do najszerszego określa, który argument operatora binarnego będzie przekształcany.
Przykład: int n = 3 ; long double z ; z = n + 3.14159 ; W ostatniej instrukcji najpierw zmienna n zostaje przekształcona do ty-pu double i jej wartość stanie się wartość równa 3.0 wartość ta zostanie dodana do 3.14159 dając wynik 6.14159 typu double a następnie otrzymany wynik zostanie przekształcony do typu long double. Przykład konwersji zwężającej: int n = 10 ; n *= 3.1 ; W drugiej instrukcji mamy dwie konwersje najpierw n jest promowane do typu double i ma wartość 10.0 po wymnożeniu przez 3.1 wynik 31.0 zostaje następnie zwężony do typu int. Ta zwężona wartość zostaje przypisana do zmiennej n. Konwersja jawna - może być wymuszona przez programistę za po-mocą jednoargumentowego operatora konwersji o składni:
(typ) wyrażenie ; lub typ (wyrażenie) ; w obu przypadkach wyrażenie zostaje przekształcone do typu typ zgodnie z regułami konwersji. Przykład: double (25) ; (double) 25 ; Oba przypadki dadzą wynik 25.0 typu double. Konwersja jawna bywa stosowana dla uniknięcia zbędnych konwersji np. wykonanie instrukcji z = n + 3.14159 ; wymaga promocji n do double a następnie zawęże-nie sumy do int. Modyfikując tę instrukcję n = n + int (3.14159) ; mamy tylko jedną konwersję z typu double do int wynik konwersji nie jest jedną wartością (wyjątek typ referencyjny), a więc można go przypi-sywać float f = float (10) ; Przykład: char a ; int b ; main () { cout << "a==" << a << '\n' ; cout << "b==" << b << '\n' ; a = 'A ' ; cout << "a po przypisaniu == " << a << endl ; b = int (a) ; cout << "(b = int (a)) == " << b << endl ; a = char (b) ; cout << "(a = (char) b) == " << a << endl ; return 0 ; } Zadeklarowanym zmiennym globalnym a i b kompilator nada automatycznie zerowe wartości początkowe: a == '\0' ; // teoretycznie b == 0 ; wydruk ma postać: a == b == 0 a po przypisaniu == A (b = int (a)) == 65 (a = (char) b) == A TabliceSkładnia: typ NazwaTablicy [LiczbaElementów] ;
Przykład: silnia [i - 1], otrzymany albo z poprzedniej iteracji pętli albo z inicjacji dokonanej przed pętlą. Program wykorzystuje drugą pętlę for do wy-świetlenia wartości silni w tablicy silnia. const max_liczba = 8 ; main () { double silnia [max_liczba + 1] ; int n ; silnia [0] = 1 ; for (int i = 1 ; i <= max_liczba ; i++) silnia [i] = i * silnia [i - 1] ; for (i = max_liczba ; i >= 0 ; i++) cout << i << " != " << silnia [i] << '\n' ; return 0 ; } C++ umożliwia deklarację i inicjację tablicy w jednym kroku np. silnia może być zadeklarowana przy pomocy następującej funkcji: double silnia [max_liczba + 1] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320} ; Liczba elementów umieszczona na liście wartości początkowych musi być mniejsza lub równa maksymalnej. Jeżeli lista jest mniejsza niż rozmiar tablicy, to kompilator przypisuje zera pozostałym elementom tablicy, które nie otrzymują bezpośrednio wartości początkowych. MacierzeSą dwuwymiarowymi tablicami, które korzystają z dwóch indeksów w celu uzyskania dostępu do swoich elementów. Składnia: char Screen [25][80] ; Przykładowy program: #include < iostream.h > #include < conio.h > #include < stdlib.h > const MaxRows = 10 ; const MaxCols = 3 ; main () { double mat [MaxRows][MaxCols] ; double sumcol [MaxCols} ; int row, col ; clrscr (); randomize () ; for (row = 0 ; row < MaxRows ; row++) for (col = 0 ; col < MaxCols ; col++) { sumcol [col] = 0 ; mat [row][col] = random(1000)/(random(500) + 1; } for (row = 0 ; row < MaxRows ; row++) for (col = 0 ; col < MaxCols ; col++) { sumcol [col] += mat [row][col] ; } for (col = 0 ; col < MaxCols ; col++) cout << "Suma kolumn #" << col << " = " << sumcol [col] << '\n' ; return 0 ; } Przykładowy wydruk: Suma kolumn #0 = 133 Suma kolumn #1 = 82 Suma kolumn #2 = 452 Ponieważ program ten wykorzystuje liczby losowe generuje różne wyni-ki przy każdym jego uruchomieniu. Program demonstruje użycie macie-zy. Wykonuje on następujące zadania:
Wychodzenie z pętliC++ umożliwia standardowo zastosowanie instrukcji break do opusz-czania pętli. Instrukcja ta powoduje przejście programu do końca aktualnej pętli. for (inicjalizacja, test, uaktualnienie) { //sekwencja instrukcji nr 1 if (warunek wyjścia z pętli) break ; //sekwencja instrukcji nr 2 } //sekwencja instrukcji nr 3 Instrukcja break działa podobnie również w innych pętlach mechanizm wychodzenia z pętli jest niezależny od typu pętli. Przykład: char s [8], FindChar ; // Podaj ciąg znaków (string) s // znak do wyszukiwania FindChar for (i = 0 ; i < strlen (s) ; i++) <= strlen() - zwraca długość łańcucha if (s [i] == FindChar) break ; if (i < strlen (s)) cout << " " << i << '\n' ; Przykładowy kod pokazuje jak instrukcja if wewnątrz pętli for może wyszukać znak w łańcuchu. Podczas gdy pętla for obrabia każdy znak w łańcuchu, instrukcja if wewnątrz pętli for określa czy znak odpowiada poszukiwanemu znakowi (FindChar). Jeśli znaleziono pasujący znak, wykonywana jest instrukcja break i pętla for kończy działanie, sterowa-nie przechodzi do instrukcji if (i < strlen (s)). Funkcja strlen () zwraca długość łańcucha podanego jako jej argument i zadeklarowana jest w pliku nagłówkowym < string.h >.
Wykaz źródeł:
| ||||||||||||||||||||||||||||||||||||||||||||||
<<POPRZEDNIA | NASTĘPNA>> | E-MAIL | |