Ogólne wiadomości o
językach
programowania
1. Wiadomości wstępne
C++
– język programowania ogólnego przeznaczenia.
Umożliwia
abstrakcję
danych
oraz
stosowanie
kilku
paradygmatów
programowania:
proceduralnego,
obiektowego i genetycznego.. Charakteryzuje się wysoką
wydajnością kodu wynikowego, bezpośrednim dostępem do
zasobów sprzętowych i funkcji systemowych, łatwością
tworzenia i korzystania z bibliotek (napisanych w C++,C lub
innych językach), niezależnością od konkretnej platformy
sprzętowej lub systemowej (co gwarantuje wysoką
przenośność
kodów
źródłowych)
oraz
niewielkim
środowiskiem uruchomieniowym. Podstawowym obszarem
jego zastosowań są aplikacje i systemy operacyjne.
C++ został zaprojektowany przez Bjarne'a Stroustrupa jako
rozszerzenie języka C o obiektowe mechanizmy abstrakcji
danych i silną statyczną kontrolę typów. Zachowanie
zgodności z językiem C na poziomie kodu źródłowego
pozostaje jednym z podstawowych celów projektowych
kolejnych standardów języka.
W latach 90. XX wieku język C++ zdobył pozycję jednego z
najpopularniejszych
języków
programowania
ogólnego
przeznaczenia. Na początku XXI wieku liczbę programistów
języka C++ szacowano na około 3 miliony
.
Od 1998 obowiązuje standard
ISO/IEC 14882:1998
(Standard for
the C++ Programming Language) z drobnymi poprawkami
zatwierdzonymi w 2003 r. (
ISO/IEC 14882:2003
). W 2009 roku
ogłoszono, że nowy standard (tzw. C++0x) zacznie obowiązywać
nie wcześniej niż w 2010 roku.
Rysunek 1 Widok głównego
widoku Winmap
Przedstawiony rysunek powyżej charakteryzuje czynności
otwierania pliku posiada kilka znaczących cech:
•
określa dokładnie kolejne kroki wykonywane przez
program;
•
wskazuje różne możliwe warianty sytuacji i dla
każdego z nich przewiduje odpowiednią reakcję
.
Algorytm jest metodą rozwiązywania problemu w skończonej
liczbie kroków (operacji elementarnych). Algorytm to
jednoznacznie
określony
sposób,
w
jaki
program
komputerowy realizuje jakąś elementarną czynność.
Przy rozwiązywaniu jakiegoś problemu przy pomocy
komputera należy zrealizować następujące etapy:
•
sformułowanie problemu (najważniejsza faza procesu
rozwiązania);
•
dokładna analiza problemu;
•
znalezienie właściwej metody rozwiązania problemu
(opracowanie algorytmu);
•
napisanie programu w określonym języku
programowania (np.
Borland C++ lub C++Builder);
•
uruchomienie i przetestowanie programu;
•
wprowadzenie koniecznych zmian.
W przypadku otwierania plików w Notatniku może to wyglądać
na przykład tak:
Algorytm
Plik -> Otwórz
Pokaż okno wyboru plików
Jeżeli
użytkownik kliknął Anuluj, To Przerwij
Jeżeli
poczyniono zmiany w aktualnym dokumencie, To
wyświetl komunikat "Czy zachować zmiany w
aktualnym
dokumencie?"
Tak,
Nie,
Anuluj
Sprawdź decyzję użytkownika
Decyzja
Tak: wywołaj polecenie Plik -> Zapisz
Decyzja
Anuluj: Przerwij
Odczytaj wybrany plik
Wyświetl zawartość pliku
Koniec
Algorytmu
Przegląd języków programowania
1.Visual Basic
Jest to następca popularnego swego czasu
języka BASIC. Zgodnie z nazwą (Basic znaczy prosty), był on
przede wszystkim łatwy do nauki. Visual Basic pozwala na
tworzenie programów dla środowiska Windows w sposób
wizualny, tzn. poprzez konstruowanie okien z takich
elementów jak przyciski czy pola tekstowe. Język ten posiada
dosyć spore możliwości, jednak ma również jedną, za to
bardzo poważną wadę
. Programy w nim napisane nie są
kompilowane w całości do kodu maszynowego, ale
interpretowane podczas działania.
Z tego powodu są znacznie
wolniejsze od tych kompilowanych całkowicie. Obecnie Visual
Basic jest jednym z języków, który umożliwia tworzenie
aplikacji pod lansowaną przez Microsoft platformę .NET, więc
pewnie jeszcze o nim usłyszymy
2.
Object Pascal (Delphi)
Delphi z kolei wywodzi się od
popularnego języka Pascal. Podobnie jak Visual Basic jest łatwy
do nauczenia, jednakże oferuje znacznie większe możliwości
zarówno jako język programowania, jak i narzędzie do tworzenia
aplikacji. Jest całkowicie kompilowany, więc działa tak szybko, jak
to tylko możliwe. Posiada również możliwość wizualnego
konstruowania okien. Dzięki temu jest to obecnie chyba
najlepsze środowisko do budowania programów użytkowych.
3.
C++
jest teraz chyba najpopularniejszym językiem do zastosowań
wszelakich. Powstało do niego bardzo wiele kompilatorów pod różne
systemy operacyjne i dlatego jest uważany za najbardziej przenośny.
Istnieje jednak druga strona medalu – mnogość tych narzędzi prowadzi
do niewielkiego rozgardiaszu i pewnych trudności w wyborze któregoś z
nich. Na szczęście sam język został w 1997 roku ostatecznie
ustandaryzowany. O C++ nie mówi się zwykle, że jest łatwy – być może
ze względu na dosyć skondensowaną składnię (na przykład
odpowiednikiem pascalowych słów begin i end są po prostu nawiasy
klamrowe { i }). To jednak dosyć powierzchowne przekonanie, a sam
język jest spójny i logiczny. Jeżeli chodzi o możliwości, to w przypadku
C++ są one bardzo duże – w sumie można powiedzieć, że nieco większe
niż Delphi. Jest on też chyba najbardziej elastyczny – niejako dopasowuje
się do preferencji programisty.
4.
Java
Ostatnimi czasy Java stała się niemal częścią
kultury masowej – wystarczy choćby wspomnieć o
telefonach komórkowych i przeznaczonych doń aplikacjach.
Ilustruje to dobrze główny cel Javy, a mianowicie
przenośność – i to nie kodu, lecz skompilowanych
programów! Osiągnięto to poprzez kompilację do tzw.
bytecode
, który jest wykonywany w ramach specjalnej
maszyny wirtualnej. W ten sposób, program w Javie może
być uruchamiany na każdej platformie, do której istnieje
maszyna wirtualna Javy – a istnieje prawie na wszystkich, od
Windowsa przez Linux, OS/2, QNX, BeOS, palmtopy czy
wreszcie nawet telefony komórkowe. Z tego właśnie powodu
Java jest wykorzystywana do pisania niewielkich programów
umieszczanych na stronach www, tak zwanych apletów.
Ceną za tą przenośność jest rzecz jasna szybkość –
bytecode Javy działa znacznie wolniej niż zwykły kod
maszynowy, w dodatku jest strasznie pamięciożerny.
Ponieważ zastosowania tego języka nie są wielkie i nie
wymagające aplikacje, lecz proste programy, zatem nie jest
to aż tak wielki mankament. Składniowo Java bardzo
przypomina C++.
5.
PHP
(skrót od Hypertext Preprocessor) jest językiem
używanym przede wszystkim w zastosowaniach internetowych,
dokładniej na stronach www. Pozwala dodać im znacznie większą
funkcjonalność niż ta oferowana przez zwykły HTML. Obecnie
miliony serwisów wykorzystuje PHP – dużą rolę w tym sukcesie
ma zapewne jego licencja, oparta na zasadach Open Source
(czyli brak ograniczeń w rozprowadzaniu i modyfikacji).
Możliwości PHP są całkiem duże, nie można tego jednak
powiedzieć o szybkości – jest to język interpretowany. Jednakże
w przypadku głównego zastosowania PHP, czyli obsłudze
serwisów internetowych, nie ma ona większego znaczenia – czas
wczytywania strony WWW to przecież w większości czas
przesyłania gotowego kodu HTML od serwera do odbiorcy. Jeżeli
chodzi o składnię, to trochę przypomina ona C++. Kod PHP
można jednak swobodnie przeplatać znacznikami HTML. Z
punktu widzenia programisty gier język ten jest w zasadzie
zupełnie bezużyteczny (chyba że kiedyś sam będziesz
wykonywał oficjalną stronę internetową swojej wielkiej produkcji
Musimy zatem zdecydować, którego języka
będziemy się uczyć, aby zrealizować nasz
nadrzędny
cel,
np.
poznanie
tajników
programowania gier. Sprecyzujmy więc wymagania
wobec owego języka:
programy w nim napisane muszą być szybkie –
w takim wypadku możemy wziąć pod uwagę
jedynie języki całkowicie
kompilowane
do kodu
maszynowego;
musi dobrze współpracować z różnorodnymi
bibliotekami graficznymi, na przykład DirectX;
powinien posiadać duże możliwości i zapewniać
gotowe, często używane rozwiązania;
nie zaszkodzi też, gdy będzie w miarę prosty i
przejrzysty.
Generacje języków programowania
Język programowania to forma zapisu instrukcji dla komputera i
programów komputerowych, pośrednia między językiem naturalnym a
kodem maszynowym.
Języki programowania można podzielić na 5 wyraźnie różniących się
generacji (według innych autorów na 4 generacje)
1.
Pierwsza generacja
– programowanie komputerów odbywa się w
kodzie binarnym, czyli za pomocą zer i jedynek. Programowanie tą
metodą stwarza ogromne trudności ze względu na to, że każdy
komputer posługuje się własnym kodem (kodem maszynowym inaczej
zwanym wewnętrznym) i programista za każdym razem musi
dostosować się do języka konkretnej maszyny.
2.
Druga generacja
–powstają języki symboliczne (asemblery), w
których ciągi zer i jedynek zastąpiono łatwiejszymi do zrozumienia
znakami mnemo- technicznymi. Chociaż języki te stanowią proste
tłumaczenie języka maszynowego na symbole i są ściśle związane z
danym modelem komputera, to znacznie ułatwiają pisanie instrukcji,
czynią je bardziej czytelnymi.
3.
Trzecia generacja
– powstają języki programowania wysokiego
poziomu, w których symbole asemblera zastąpiono łatwiejszym do
zapamiętania językiem naturalny.
4.
Czwarta generacja
– odpowiednie narzędzia umożliwiają
budowanie prostych aplikacji dzięki wykorzystaniu gotowych modułów.
5.
Piąta generacja
– to języki stosowane do tworzenia programów
wykorzystują-cych tzw. sztuczną inteligencję lub systemów
(ekspertowych)
Metody programowania
1 Programowanie proceduralne
Zadecyduj, jakie chcesz mieć procedury; stosuj najlepsze
algorytmy, jakie możesz znaleźć
2. Programowanie modularne (strukturalne)
Zadecyduj, jakie chcesz mieć moduły:
podziel program w taki sposób, aby ukryć dane w modułach:
Programowanie strukturalne to paradygmat programowania
zalecający hierarchiczne dzielenie kodu na moduły, które
komunikują się jedynie poprzez dobrze określone interfejsy. Jest
to rozszerzenie koncepcji programowania proceduralnego
3. Programowanie obiektowe
Ewolucja języków strukturalnych wykreowała w
latach 80 – tych
języki obiektowe i programowanie
obiektowe
. Programowanie to jest nowym
sposobem programowania, w którym program jest
rozumiany jako zespół obiektów wzajemnie na
siebie oddziaływujących. Klasyczne programowanie
oparte jest na procedurach i instrukcji skoku
bezwarunkowego GOTO miało pewne wady, które
wyeliminowało programowanie strukturalne. Nie
był to postęp wystarczający z punktu widzenia
programisty, w miarę jak rosły złożoność i stopień
skomplikowania programów.
Programowanie obiektowe (ang. object-oriented programming)
to metodologia tworzenia programów komputerowych, która
definiuje programy za pomocą "obiektów" - elementów łączących
stan (czyli dane) i zachowanie (czyli procedury, tu: metody).
Obiektowy program komputerowy wyrażony jest jako zbiór takich
obiektów, komunikujących się pomiędzy sobą w celu wykonywania
zadań. Podejście to różni się od tradycyjnego programowania
proceduralnego, gdzie dane i procedury nie są ze sobą
bezpośrednio związane. Programowanie obiektowe ma ułatwić
pisanie, konserwację i wielokrotne użycie programów lub ich
fragmentów
Programowanie proceduralne to paradygmat programowania
zalecający dzielenie kodu na procedury, czyli fragmenty
wykonujące ściśle określone operacje.
Procedury nie powinny korzystać ze zmiennych globalnych (w
miarę możliwości), lecz pobierać i przekazywać wszystkie dane
(czy też wskaźniki do nich) jako parametry wywołania
4.Programowanie wizualne
Po ogromny sukcesie Delphi firma Borland
postanowiła stworzyć podobne narzędzie dla języka
C++. Nowy produkt w znacznej części wykorzystuje
filozofię Delphi.
C++ Builder to:
32 bitowe, w pełni zintegrowane środowisko RAD
(Rapid Application Development) do szybkiego
tworzenia aplikacji w systemie operacyjnym
Windows;
wygodne wizualne środowisko programowania
IDE (Integrated Development Enviroment)
wspomagane biblioteką wizualnych komponentów
VCL (Visual Component Library). Dzięki temu
pisanie
programów
w
takim
środowisku
programowania sprowadza się do wybrania
komponentów i przeciągnięcia ich do obszaru
projektowania.
Ogólne wiadomości o języku C i C++
1. Zmienne
Zmienna
(ang. variable) to miejsce w pamięci operacyjnej,
przechowujące pojedynczą wartość określonego typu. Każda
zmienna ma nazwę, dzięki której można się do niej odwoływać.
Typy podstawowe
Typy całkowite
Typ
Rozmi
ar
Przedział wartości
(decymalnie)
char
unsigned
char
signed char
1 byte
1 byte
1 byte
-129 do +127 lub 0 do 255
0 do 255
-128 do +127
int
unsigned int
2 byte
4 byte
2 byte
4 byte
-32768 do +32767
-2147483648 do +2147483647
0 do 65535
0 do 4294967295
short
unsigned
short
2 byte
2 byte
-32768 do +32767
0 do 65535
long
unsigned
long
4 byte
4 byte
-2147483648 do +2147483647
0 do 4294967295
Modyfikatory typu:
signed
ze znakiem (), int
char
unsigned
bez znaku, int
char
short
krótka (mniejsza),
int
long długa (większa) int
double
np. unsigned long int dluga_liczba_bez_znaku ;Wartości domyślne:
long
=
long int
int
=
signed int
char
=
signed char
Rys. Przedział wartości typów liczbowych ze znakiem (signed) i bez znaku (unsigned)
Type
Rozmi
ar
Dolna
dodatnia
wartość
Przedzia
ł wartości
Dokładno
ść
(decymalni
e)
float
4 byte
-3.4E+38
1.2E-38
6 cyfr
doubl
e
8 byte
-
1.7E+308
2.3E-308
15 cyfr
long
double
10
byte
-
1.1E+4932
3.4E-
4932
19 cyfr
Typy rzeczywiste
Pojedynczy
znak
Znaczenie
Kod
ASCI
\a
alert (BEL)
7
\b
backspace (BS)
8
\t
horizontal tab (HT)
9
\n
line feed (LF) (przejście do nowej
linii)
10
\v
vertical tab (VT) (przejście do nowej
kolumny)
11
\f
form feed (FF) wysuw strony)
12
\r
carriage return (CR) powrót karetki
drukarki)
13
\”
double quote ( podwójny cudzysłów
34
\’
single quote (pojedynczy
cudzosłów)
39
\?
guestion mark (znak zapytania)
63
\\
backslash
92
\0
string terminating charakter (koniec
stringa)
0
\ooo
(up to 3 digits)
numeryczna wartość znaku
ooo (octal)
\xhh
(hexadecimal digits)
numeryczna wartość znaku
hh
(hexidecimal
Typy wyliczeniowe
W C i C++ istnieje możliwość definiowania zmiennych
wyliczeniowych. Typ wyliczeniowy służy do definiowania
zbiorów stałych całkowitych. Ogólny schemat definicji typu
wyliczeniowego przedstawia się następująco:
enum identyfikator-_typu_wyliczeniowego
{
….lista stałych wyliczeniowych
}
[zmienna –typu wyliczeniowego[=inicjator]];
przykład
enum months
{
Jan,Fab,Mar,Apr,mai,Jun,Jul,Aug,Sep,Okt,Nov,dec
};
Typ void
Jest to typ pusty. Wykorzystywany bywa w następujących
sytuacjach:
po pierwsze, za jego pomocą możemy deklarować funkcje
nie zwracające żadnych wartości;
po drugie możemy deklarować funkcje, które nie
pobierają argumentów;
po trzecie umożliwia on tworzenie ogólnych wskaźników
.
Zasada nadawania wartości stałym
Jeśli brak jest bezpośrednich inicjatorów (tak jak w
przykładzie), pierwszej stałej nadawana jest wartość
zero, a każdej następnej o jeden większa od
poprzedniej (a więc 0,1,2,3...,) W przypadku
wystąpienia inicjatora stałej nadawana jest wartość
zgodna z ta wskazana w inicjatorze, zaś następne
stałe inicjatora są inicjowane kolejnymi wartościami
całkowitymi.
enum months
{
Jan=10,fab,Mar,Apr=20,May=Jan+Apr,Jun,Jul,A
ug,Sep,Okt,Nov,
Dec=50
};
Typy w Windows
Typ Windows
Znaczenie
BOOL
int z dwoma wartościami TRUE oraz
FALSE
BYTE
unsigned char
DWORD
unsigned long
LPDWORD
unsigned long *
LONG
long
LPLONG
long *
LPCSTR
const char *
LPCTSTR
unsigned const char *
LPSTR
char *
LPVOID lub Pointer
void *
LPCVOID
const void *
UINT
unsigned int
WORD
unsigned short
Typy logiczne
Zmienne mogące przyjmować tylko dwie wartości: true (prawda)
lub false (fałsz) cha-akteryzują cztery podstawowe typy logiczne,
które są zamieszone w tabeli poniżej.
Typ
Rozmiar (bajty)
bool
1
boolean
(dostępny w VCL)
1
ByteBool
(dostępny w VCL)
1
WordBool
(dostępny w VCL)
2
LongBoo
l (dostępny w VCL)
4
Typy znakowe
Typ
Zawartość
Rozmiar
(bajty)
char
Pojedynczy
znak
ASCII
1
wchar_t
Pojedynczy
znak
UNICODE
2
AnsiChar
(dostępny w VCL)
Pojedynczy
znak
ASCII
1
WideChar
(dostępny w VCL)
Pojedynczy
znak
UNICODE
2
Typy łańcuchowe
Typ
Zawartość
Rozmiar
(bajty)
SmallString<rozmi
ar>
255 znaków Od 1 do 256
SortString
255 znaków Od 2 do 256
AnsiString
~2^31
znaków
Od 4 do 2GB
WideString
~2^30
znaków
Od 4 do 2GB
string message = "Good
Morning!";
Stałe
Stała
to niezmienna wartość, której nadano nazwę celem
łatwego jej odróżnienia od innych, często podobnych wartości,
w kodzie programu.
Jej deklaracja, na przykład taka:
const int
STALA =
10
;
Stałe mają też tę zaletę, że ich wartości możemy określać za
pomocą innych stałych, na przykład:
const int
NETTO =
2000
;
const int
PODATEK =
22
;
const int
BRUTTO = NETTO + NETTO * PODATEK /
100
;
Inne przykłady stałych:
const int
DNI_W_TYGODNIU =
7
;
// :-)
const float
PI =
3.141592653589793
;
// w końcu to
też stała!
const int
MAX_POZIOM =
50
;
// np. w grze RPG
Strumień wejścia i wyjścia
cout<<”podaj Imie”;
cin >> strImie
;
Zauważmy, że w naszej aplikacji kursor pojawia się w tej
samej linijce, co komunikat „Podaj swoje imię”. Nietrudno
domyśleć się, dlaczego – nie umieściliśmy po nim endl, wobec
czego nie jest wykonywane przejście do następnego wiersza.
Jednocześnie znaczy to, iż strumień wejścia zawsze pokazuje
kursor tam, gdzie skończyliśmy pisanie – warto o tym
pamiętać
.
Operatory
Operator
Oznaczenie
+
dodawanie
-
odejmowanie
*
mnożenie
/
dzielenie
%
reszta dzielenia
Operatory algebraiczne
Binarne operatory
Operatory relacyjne
Operat
or
Znaczenie
<
<=
mniejsze niż
mniejsze
równe
.>
>=
większe niż
większe równe
==
!=
równe
nierówne
Operatory logiczne
A
!A
true
false
false
true
Przykłady równań logicznych
x
y
Równanie
logiczne
wynik
1
-1
x <= y || y > = 0
false
0
0
x >-2 && y == 0
true
-1
0
x && !y
true
0
1
!(x+1) || y-1>0
false
operatory przypisania
:
= zwykłe przypisanie
x = 2;
+= przypisanie sumy
x+=2;
x = x + 2;
= przypisanie różnicy x=2; x = x 2;
= przypisanie iloczynu x=2;
x = x 2;
/= przypisanie ilorazu
x /=2; x = x / 2;
%= przypisanie reszty
x%=2; x = x % 2;
&= przypisanie iloczynu bitowego x &=0x02;
|= przypisanie sumy
bitowej x |=0x02;
operatory inkrementacji i dekrementacji
:
zmienna++
inkrementacja zmiennej po wyliczeniu
wyrażenia
++zmienna
inkrementacja zmiennej przed wyliczeniem
wyrażenia
zmienna
dekrementacja zmiennej po wyliczeniu
wyrażenia
zmienna
dekrementacja zmiennej przed wyliczeniem
wyrażenia
np. int x, y = 1;
x = y ;
rezultat: x=2, y=2
x = y ;
rezultat: x=1, y=2
bitowe operatory logiczne
:
& bitowa koniunkcja (AND); | bitowa alternatywa
(OR);
^ bitowa różnica symetryczna (XOR); << przesunięcie
bitów w lewo
>> przesunięcie bitów w prawo; ~ negacja
bitowa
Bitowa koniunkcja
to operator dwuargumentowy. Zapis f =
a&b oznacza że bity w liczbie f są jedynkami, o ile oba bity na
tych samych pozycjach w liczbach a i b są jedynkami.
Np.
a = 7&4 = (00000111)U2&(00000100)U2 = (00000100)U2 =
4
00000111
00000100
----------------
00000100
b = 100&57 = (01100100)U2&(00111001)U2= (00100000)U2
= 32
c
=
(-25)&55
=
(11100111)U2&(00110111)U2
=
(00100111)U2 = 39
Bitowa alternatywa
jest operatorem dwuargumentowym.
Zapis f = a|b oznacza że w liczbie f jedynki ustawiane są na tych
pozycjach, na których znajdowały się jedynki w liczbach a i b.
Np.
a = 7|4 = (00000111)U2|(00000100)U2 = (00000111)U2 = 7
b = 100|57 = (01100100)U2|(00111001)U2 = (01111101)U2
=125
c = (-25)|55 = (11100111)U2|(00110111)U2 = (11110111)U2 =
-9
Bitowa różnica symetryczna
, czyli operacja XOR, powoduje,
że włączone zostają te bity, które miały różne stany w obu
argumentach. Pozostałe bity zostają wyłączone. Wynik operacji
XOR na pojedynczych bitach obrazuje tabela:
Argumen
t1
Argument
2
Wynik
1
1
0
1
0
1
0
1
1
0
0
0
Operacja XOR
będzie zatem wyglądała następująco:
00100010 (34)
01110110 (118)
---------------------
01010100 (84)
bitowe przesunięcie w prawo.
Zapis f = a>>n oznacza że z liczby a zabieramy n bitów
przesuwając wszystkie bity w prawo. Przy przesunięciu o jeden
bit wszystkie bity są przesuwane o jedną pozycję w prawo a
najstarszy bit zachowuje swoją dotychczasowa wartość.
Operacja ta odpowiada podzieleniu liczby przez 2n i
zaokrągleniu wyniku w dół. Ma to znaczenie w liczbach
ujemnych.
Np.
a = 80>>2 = (01010000)U2>>2 = (00010100)U2 = 20
b =127>>5 = (01111111)U2>>5 = (00000011)U2 = 3
c = -15>>2 = (11110001)U2>>2 = (11111100)U2 = -4
d = -15/4 = -3. bitowe przesunięcie w prawo.
operatory jednoargumentowe
wyłuskanie int x=*y;
& adres obiektu (referencja) int* x =&y;
operatory związane z klasami i strukturami
:: operator zakresu Klasa::funkcja();
-> operator dostępu pośredniego Klasa->funkcja():
. operator dostępu bezpośredniego Klasa.funkcja();
Priorytety operatorów w języku C:
Operator
Opis
Przykład
( ) wywołanie funkcji sin()
[ ] element tablicy tab[10]
. element struktury
osoba.nazwisko
wskazanie elementu struktury
wsk_osobynazwisko
! negacja logiczna if( ! (x
max) ) kontynuuj;
~ negacja bitowa
~(001101) (110010)
zmiana znaku (negacja) x = 10 (
y)
inkrementacja (zwiększenie o 1) x y
(x ) y
dekrementacja (zmniejszenie o 1) y
y ( y)
& operator referencji (adres elementu) wsk_x =
&x
operator dereferencji wsk_x =
10
(type) zmiana typu (typecast ) (double)
10 10.0
sizeof rozmiar zmiennej lub typu (w bajtach sizeof( int )
2
mnożenie
/ dzielenie
% operacja modulo (reszta z dzielenia) if( x%2 ==
0 ) parzyste;
dodawanie
odejmowanie
przesunięcie bitowe w lewo 1 2
(0001) 2 (0100)
przesuniecie bitowe w prawo
x 4 1 x 2
mniejszy niż if( liczba max ) max
liczba;
mniejszy lub równy
większy niż
większy lub równy
równy
! nierówny (różny od)
& iloczyn bitowy
^ suma bitowa modulo (różnica symetryczna)
| suma bitowa
&& iloczyn logiczny
|| suma logiczna
? : wyrażenie warunkowe
przypisanie
/ %
przypisania arytmetyczne
& ^ |
, operator przecinka
Nawiasy chronią przed trudnymi do wykrycia błędami
związanymi z pierwszeństwem operatorów, dlatego stosuj je w
przypadku każdej wątpliwości co do kolejności działań.
Tablice
array[0]
array[1]
array[2]
.
.
.
.
.
.
.
.
array[7]
Tablica w pamięci
Tablice znakowe w pamięci
Inicjowanie
char text[40] = "Hello Eve";
‘H
’‘E
’‘L’‘L’‘O
’“‘E
’‘W
’‘A
’.
Tekst posiada długość 40,ale string wykorzystuje
tylko 9 bajtów
Znacznikiem końca łańcucha (ang. terminatting null) jest w
C i C++ znak o kodzie 0, zapisywany symbolicznie w postaci \
0. Z tego powodu łańcuchy używane w C++ często są
określane mianem łańcuchów zakończonych zerem lub ASCIIZ
(ASCII-zero).
Funkcje operujące na tablicach
Funkcja
Działanie
strcat()
Łączy (skleja) dwa łańcuchy.
strcmp() Porównuje dwa łańcuchy.
strcmpi() Porównuje dwa łańcuchy bez rozróżniania małych
i dużych liter
strcpy()
Kopiuje zawartość jednego łańcucha do drugiego
strstr()
Wyszukuje zadany ciąg znaków w łańcuchu
strlen()
Zwraca długość łańcucha (bez kończącego znaku
\0.
strupr()
Zmienia wszystkie małe litery w łańcuchu na
duże
sprintf() Tworzy łańcuch z zadanych argumentów,
wykorzystując wzorzec formatu
Omawiane tutaj funkcje operujące na łańcuchach wchodzą w
skład
podstawowych
bibliotek
języka
C.
Większość
kompilatorów C++ oferuje programiście klasę o nazwie cstring
lub podobną, której zadaniem jest uproszczenie złożonego
sposobu manipulowania łańcuchami. W systemie C++Builder
klasą taką jest klasą AnsiString, wchodzącą w skład biblioteki
VCL.
Nieco
skomplikowany
sposób
obsługi
danych
łańcuchowych nie oznacza bynajmniej, że standardowe funkcje
biblioteczne C są zarzucane na korzyść funkcji zdefiniowanych
w klasach cstring lub AnsiString – oba podejścia są
równoważne i równie skuteczne.
Ostrzeżenie: Przypadkowe odwołanie do danych leżących
poza końcem tablicy znakowej jest znacznie łatwiejsze, niż w
przypadku tablic liczb. Wystarczy zrobić coś takiego:
Morał: kopiując dane łańcuchowe, uważaj, co robisz.
Reguły gry
: tablice
Tablice są zawsze indeksowane od zera. Pierwszy element
tablicy
(jednowymiarowej) ma numer 0, drugi – 1 i tak dalej;
Rozmiar tablicy musi być ustalony w chwili kompilacji. jest to
konieczne, by kompilator mógł zarezerwować dla tablicy blok
pamięci odpowiedniej wielkości. próba wykorzystania zmiennej
do określenia rozmiaru deklarowanej tablicy, jak w poniższym
przykładzie jest nielegalna i zakończy się błędem kompilacji:
int x=10;
int mojaTablica[x]; // błąd: rozmiar tablicy musi
być stałą
Należy pilnie wystrzegać się prób zapisywania danych poza
końcem tablicy.
Większe tablice lepiej jest tworzyć dynamicznie (na stercie)
niż statycznie lub lokalnie (na stosie). Pojęcia te będą
omówione później.
W przypadku tablic tworzonych dynamicznie możliwe jest
ustalanie ich wielkości za pomocą zmiennych, np. tak:
int x=10;
int* TabInt = new int[x]; // dopuszczalne
Tablice łańcuchów
Wiemy już, że łańcuchy znaków są reprezentowane w
postaci tablic znaków. Te z kolei można organizować w
tablice łańcuchów, czyli tablice tablic. Przykład użycia tablicy
znaków mamy już za sobą. Oto inny przykład deklaracji i
inicjalizacji łańcuchów:
char string[][20] ={
”Pierwszy napis”,
”Drugi napis’”,
”Trzeci napis”,
”Czwarty napis”
};