RÓŻNE

Wstęp

Chętni do współpracy

Darmowa prenumerata

Redakcja

Listy

Reklama

SOFTWARE

WinZip vs. Win Rar

CDex

Bankrut

HARDWARE

Komputer doskonały

Podkręcanie

INTERNET

Bankier.pl

Za e-maile pieniądze? 

Ciekawe strony

GRY

The Sims

Colin McRae 2.0 

FIFA 2001

Screeny

Tipsy

KURSY

Kurs HTML-a #1

Kurs Object Pascala

 

 

KURS OBJECT PASCAL

WSTĘP

Mniej więcej w roku 1984 Borland zaczął pracę nad narzędziem RAD (ang. Rapid Application Development - oznacza błyskawiczne tworzenie aplikacji) pod roboczą nazwą Delphi. Kiedy zdecydowano, że najlepszym modelem do realizacji RAD będzie architektura oparta na komponentach, trzeba było zdecydować się na jakiś język programowania, na którym bazowałoby wszystko.

W tym okresie Borland znany był jako producent najlepszych narzędzi i kompilatorów Pascal'a. Jeżeli programowałeś w Pascalu, to prawdopodobnie używałeś którejś wersji Turbo Pascal'a. Pascal zawsze był mocno związany z Borland'em. Mimo, że Borland nie posiadał praw do Pascal'a, to często wprowadzał do niego nowe standardy i rozszerzenia. Borland stworzył więc Delphi z Pascalem jako językiem bazowym.

Zanim Delphi wogóle zaistniało, Borland wprowadził do Pascal'a znaczne ulepszenia tworząc w ten sposób nowy język programowania zwany Borland Pascal'em. Można powiedzieć, że Borland Pascal ma się do Pascal'a, jak C++ do C. Object Pascal posiadał już klasy i był zaliczany do rodziny języków obiektowo zorientowanych. Wraz z rozwojem Delphi wprowadzano do niego nowe elementy i słowa kluczowe. W rezultacie współpraca Borland Pascal'a i Delphi stała się niemal doskonała.

Borland modyfikując Pascal'a wziął na siebie spore ryzyko, ale rezultat okazał się hitem rynkowym.

Moim skromnym zdaniem Object Pascal jest bardzo silnym językiem programowania. Można z nim naprawdę wiele zdziałać! Delphi ma tę zaletę, że jest silne i względnie łatwe do opanowania. Nie twierdzę jednak, że Object Pascal jest "niepełnowartościowym" językiem programowania. Krążyły opinie, że nie jest on tak "poważny" jak C, jednak nie jest to wcale prawdą, zwłaszcza w przypadku dzisiejszego Object Pascal'a.

Object Pascal pozwala w pełni wykorzystywać zalety programowania obiektowo zorientowanego. OOP (ang. Object-Oriented Programming) nie jest tylko modnym sloganem, pozwala bowiem tworzyć obiekty wykorzystywane w każdym projekcie. Obiekt udostępniony jest programiście w stopniu możliwie najmniejszym, co znacznie ułatwia korzystanie z niego, ponieważ programista nie musi wiedzieć o wszystkich wewnętrznych mechanizmach. Umożliwia to "modułowe" podejście do programowania. Dzięki temu nie trzeba za każdym razem "wynajdywać koła", czyli robić tego, co zrobili już inni. Programy Delphi są silnie OOP - centryczne, ponieważ w bardzo dużym stopniu wykorzystują komponenty. Chodzi o to, że jeśli jakiś komponent zostanie już wbudowany w Delphi, to może być wykorzystywany w różnych projektach, co więcej może być podstawą dla nowego komponentu o większych możliwościach.

KOMENTARZE

Komentarze są dla kompliatora znakami, które ignoruje. Natomiast dla programisty są bardzo użyteczne, ponieważ pozwalają umieszczać w kodzie dowolne informacje, które zwiększają czytelność programu i pozwalają szybciej zrozumieć "o co chodzi" w danej procedurze czy poleceniu. Oto przykład:

//To jest komentarz jednoliniowy

{a to jest już
komentarz
wieloliniowy}

(* jeśli nie podobają Ci się
nawiasy klamrowe możesz użyć
zwykłego nawiasu i gwiazdki
do oznaczania komentarza.
Jest on jednak rzadko używany.*)

STAŁE

Stałe są nazwami, które posiadają niezmienną wartość. Deklarujemy je w programie tylko raz i używamy przez cały czas. Zalety używania stałych:
  • Mamy możliwość wprowadzania szybkich zmian, ponieważ np. zmieniamy wartość stałej w miejscu deklaracji, a automatycznie zmienia się jej wartość we wszystkich miejscach, w których się do niej odwołaliśmy.
  • Używanie stałych zwiększa przejrzystość programu.
Stałe deklarujemy po słowie kluczowym const. Oto przykład:

const

 StawkaPodatku = 0.22

 MojeImie = 'Michał'

 LiczbaBraci = 1

Zauważ, że do deklaracji stałej używa się znaku równości i nie określa się typu. Kompilator zrobi to sam za Ciebie.

ZMIENNE

Zmienne różnią się od stałych znacznie. Jak sama nazwa wskazuje - stałym przypisujemy wartość, której nie możemy zmienić, natomiast zmiennym możemy w dowolnym momencie przypisać wybraną wartość.. Ważną różnicą jest również to, że w czasie deklarowania zmiennej musimy określić jej typ, którego później nie możemy już zmienić. Zmienne deklarujemy po słowie kluczowym var. Oto przykład:


var

Wiek: Integer;

natomiast dalej w procedurze możemy przypisać jej jakąś wartość np.

Wiek := 15;

Ważne jest, aby deklaracja zmiennej była zakończona średnikiem !!! Nazwy zmiennych (również stałych, procedur, funkcji itp.) muszą spełniać kilka warunków:

  1. Mogą się składać jedynie z dużych i małych liter alfabetu angielskiego, a także z cyfr i znaku podkreślenia (_).
  2. Nie mogą zawierać spacji i innych znaków specjalnych.
  3. Na początku musi być litera albo znak podkreślenia.
  4. Długość nazwy może być dowolna, ale pod uwagę brane jest tylko 255 pierwszych znaków.

Object Pascal jest pobłażliwy w przypadku małych i dużych liter. Wszystkie poniższe identyfikatory są dla kompilatora jednakowe:

  • Nazwa_Identyfikatora
  • NAZWA_IDENTYFIKATORA
  • nazwa_identyfikatora
  • NaZwA_IdEnTyFiKaToRa

TYPY PROSTE

Kiedy ktoś pyta nas o odległoś do jakiegoś miasta, to nie podajemy mu jej w milimetrach, tylko mówimy np. 30 km. Tak samo jest z przechowywaniem danych. Jeśli chcemy zapamiętać liczbę np. 1, to nie użyjemy do tego bloku pamięci, który zapamiętałby liczbę -12583689,482. Oczywiście jest to możliwe, ale to zwykłe marnotrawstwo. Nawet najlepsze komputery mają ograniczoną ilośc pamięci i taka rozrzutność może się skończyć nieciekawie. Object Pascal jest pod tym względem bardzo rygorystycznym językiem. Deklarując zmienną lub stałą musimy ściśle określić jej typ, czyli blok pamięci, który komputer zarezerwuje do jej przechowywania. Niektórzy twierdzą, że Object Pascal jest dla osób roztargnionych, ale osobiście uważam, że to nieprawda i rygor w operwowaniu typami zmiennych zmniejsza ilość błędów oraz zwiększa przejrzystość programu

TYPY CAŁKOWITE

Typy całkowite służą do przechowywania liczb całkowitych. Oto one:

Typ Zakres wartości Rozmiar (w bajtach)
Byte 0...255 1
Word 0...65535 2
ShortInt -128..127 1
SmallInt -32768...32767 2
Integer -2147483648...2147483647 4
Cardinal 0...2147483648 4
LongInt -2147483648...2147483647 4

Jak widzisz zakres przechowywanych wartości ma swoją cenę w postaci bajtów zajmowanej pamięci. Dlatego pamiętaj, aby rozważnie gospodarować zasobami pamięci !

Aby lepiej poznać typy całkowite napiszemy prosty program, który będzie podnosił liczbę do kwadratu. Możesz go pobrać stąd lub przygotować samemu. Pomoże Ci w tym zdjęcie formy.

Otwórz nowy projekt. Do formy wstaw komponent Edit, a jego cechę Text ustaw na pustą. Wstaw komponent Button i jego cechę Caption zmień na "Do kwadratu". Na koniec umieść jeszcze trzy komponenty Label. Jeden będzie z napisem "Liczba", drugi "Wynik:", a ostatni umieść obok "Wynik:", a jego cechę Caption ustaw na pustą (stanie się niewidoczny). Poniższa procedura jest dla zdarzenia OnClick naszego przycisku.

procedure TForm1.Button1Click(Sender: TObject);
var
Liczba: Integer;
Wynik: LongInt;
begin
Liczba:=StrToInt(Edit1.Text);
Wynik:=Liczba*Liczba;
Label4.Caption:=IntToStr(Wynik);
end;

W naszej procedurze deklarujemy dwie zmienne: Liczba typu Integer i Wynik typu LongInt. W pierwszej linii pobieramy wartość zmiennej Liczba. Następnie zmiennej Wynik przypisujemy wartość zmiennej Liczba podniesionej do kwadratu. Na koniec wyświetlamy wynik w etykiecie Label4, która jest na początku niewidoczna.

Przyjrzyj się jeszcze raz w tabeli jakie maksymalne wartości mogą przyjąć zmienne typu Integer i LongInt? A co by się stało, gdybyśmy chcieli podnieść liczbę z poza zakresu Integer? Spróbuj podnieść do kwadratu np. liczbę 3452748425. Otrzymamy komunikat '3452748425 is not a valid integer value', czyli że liczba 3452748425 nie należy do zakresu wartości Integer. Jest to przykład jednego z najczęstrzych błędów, kiedy użytkownik wprowadza niedozwoloną wartość, ale można się przed tym ochronić na wiele sposobów. Narazie należy pamiętać, że trzeba starać się dobierać typ do zmiennej tak, aby nigdy jej wartość nie przekroczyła dopuszczalnego zakresu. To by było na tyle o typach całkowitych. Więcej informacji znajdziesz w pomocy Delphi i fachowej literaturze.

TYPY RZECZYWISTE

Typy rzeczywiste różnią się od całkowitych tym, że oprócz części całkowitej mogą jeszcze zawierać części ułamkowe, czyli liczby po przecinku. Dzięki temu mają one o wiele większy zakres wartości, ale kosztem zajmowania większej ilości pamięci.

Typ Zakres wartości Rozmiar (w bajtach)
Real 2.9*10-39...1.7*1038 6
Single 1.5*10-45...3.4*1038 4
Double 5.0*10-324...1.7*10308 8
Extended 3.4*10-4932...1.1*104392 10
Comp -2-63...2-63 -1 8

Typ Comp jest tak naprawdę typem całkowitym, ale umieściłem go w tej tabeli ze względu na ilość zajmowanego miejsca w pamięci.

A teraz prosty przykład. Nasz program będzie dodawał do siebie dwie liczby rzeczywiste. Możesz go pobrać stąd lub przygotować samemu. W tym celu należy utworzyć nowy projekt i umieścić w formie siedem komponentów. Pierwszy zaczynając od góry to etykieta "Liczba", następnie komponent Edit (cechę Text ustaw na pustą) analogicznie etykieta i Edit dla drugiej liczby. Następni umieśc w formularzu dwie etykiety. Pierwsza "Wynik", a druga pusta obok. Ostatni jest przycisk "Dodaj".Oto końcowy wygląd naszej formy:

A oto procedura obsługując zdarzenie OnClick naszego przycisku:

procedure TForm1.Button1Click(Sender: TObject);
var
Liczba1, Liczba2: Double;
begin
Liczba1 := StrToFloat(Edit1.Text);
Liczba2 := StrToFloat(Edit2.Text);
Label4.Caption := FloatToStr(Liczba1 + Liczba2);
end;

W naszej bardzo prostej procedurze inicjalizujemy dwie zmienne Liczba1 i Liczba2 typu Double następnie przypisujemy im wartości okienek Edit. Na koniec przypisujemy etykiecie (niewidocznej na początku, bo jej cecha Caption ustawiona jest na pustą) wartość sumy naszych liczb. Ciekawostką może tu być konwersja typu Double na String, która jest niezbędna, ponieważ cecha Caption etykiety może być tylko typu String. Nasz prosty program działa poprawnie i dodaje liczby z cyframi po przecinku. Niestety nie jest on bezbłędny, ponieważ nie obsługuje on wielu wyjątków jak np. nie podanie tylko jednej z liczb, czy podanie tekstu zamiast liczby itp. O tym jak uchronić się przed tego typu błędami można napisać cały artykół i może zrobię to w przyszłości :)

Wszędzie tam, gdzie to możliwe, używaj zmiennych typu Single lub Double zamiast Real. Przyspieszą one obliczenia, ponieważ odpowiadają bezpośrednio formatowi, który obsługiwany jest przez koprocesor arytmetyczny. W przypadku typu Real za każdym razem konieczne jest dokonywanie konwersji

TYP CURRENCY

Typ Currency pojawił się dopiero w Delphi 3 i służy do przechowywania wartości określającej kwotę pieniężną. Do tej pory taką wartość przechowywało się w zmiennej typu rzeczywistego. Jaka jest różnica między typem rzeczywistym np. Double a Currency? Główna różnica polega na formacie (64 bity, precyzja do czterech miejsc po przecinku) i zakresie wartości, który wynosi -922,337,203,685,477.5808 do 922,337,203,685,477.5807

Myślę, że nie będzie tu potrzebny przykład, ponieważ tego typu używa się bardzo rzadko. Jeśli będziesz miał trudności to napisz. Postaram się pomóc :)

TYP LOGICZNY

Typy logiczne pochodzą z rodziny Boolean i są bardzo proste w użyciu. Służyą one do przechowywania dwóch wartości PRAWDA i FAŁSZ , czyli TRUE i FALSE lub 1 i 0. Kiedy spojrzysz na poniższą tabelę zapytasz zapewne: "Po co aż tyle odmian typów logicznych?". Odpowiedź jest dosyć prosta. System Windows wymaga czasem, aby zmienna logiczna zapisana była w 4 bajtach i dlatego konieczna jest zgodność.

Typ Rozmiar
(w bajtach)
Boolean 1
ByteBool 1
Bool 2
WordBool 2
LongBool 4

Tutaj już niestety nie obejdzie się bez przykładu :). Jak zwykle możesz go pobrać stąd lub przygotować samemu. Ten obrazek Ci w tym pomoże.

Nasz programik będzi badał gust użytkownika. Wstaw pięć CheckBox'ów i nadaj im odpowiednie cechy Caption. Wstaw również przycisk "Odpowiedź" i etykiety po prawo (ważne, żeby miały takie nazwy!). Oto procedura OnClick naszego przycisku:

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'Dziękuję za odpowiedź. Oto co lubisz jeść:';
If CheckBox1.Checked = True then
   Label2.Caption := 'Lubisz jeść Pizzę !';
If CheckBox2.Checked = True then
   Label3.Caption := 'Lubisz jeść Schabowe (ja też)';
If CheckBox3.Checked = True then
   Label4.Caption := 'Lubisz jeść Kurczaki';
If CheckBox4.Checked = True then
   Label5.Caption := 'Lubisz jeść Spagetii';
If CheckBox5.Checked = True then
   Label6.Caption := 'Lubisz jeść coś innego. Co...';
end;

Nasz program sprawdza czy komponent CheckBox został zaznaczony (właściwość Checked) i jeśli tak, to wyświetla w etykiecie odpowiedni napis. Ze względów na przejrzystość programu nie chciałem go bardziej komplikować, dlatego nie wykrywa on, czy przynajmniej jedna odpowiedź została zaznaczona i nie czyści etykiet przy następnym odpowiadaniu. W ramach ćwiczeń możesz poprawić ten program conajmniej o te błędy :)

TYPY ZNAKOWE

Typy znakowe służą do przechowywania jednego znaku. W zmiennej typu Char zapamiętać możemy jeden z 256 różnych znaków.

Typ Rozmiar (w bajtach) Opis
ANSIChar 1 1 znak ANSI
WideChar 2 1 znak Unicode
Char 1 Obecnie (Delphi 3) odpowiada typowi ANSIChar. *
* - może ulec zmianom w przyszłych wersjach.

Nowością od Delphi 3 jest rozszerzenie zbioru typów znakowych. Wprowadzono nowy typ ANSIChar, który jest odpowiednikiem typu Char i służy do reprezentowania 8-bitowych znaków ANSI. Dodano także nowy typ znakowy: WidrChar, w którym zapisywane są znaki na 16 bitach. Delphi 3 obsługuje boweim standard Unicode, w którym tak właśnie koduje się znaki.

Praktyczne zastosowanie typu Char pokarzemy w programie, który będzie zmieniał kod ANSI znaku na sam znak. Program ten możesz pobrać stąd lub przygotować samemu. Umieść w formie komonent SpinEdit z karty Samlpes, dwie etykiety: "Znak" oraz pustą (u nas to Label 1) i przycisk "Kod na Znak". Oto zdjęcie formy i procedura OnClick tego przycisku:


procedure TForm1.Button1Click(Sender: TObject);
var
znak: Char;
begin
znak := Char(StrToInt(SpinEdit1.Text));
Label1.Caption := znak;
end;

W naszej procedurze deklarujemy zmienną znak typu Char. Następnie przypisujemy jej wartość kodu ANSI znaku, który jest pod tym numerem na liście ANSI i konwertujemy na znak. Na koniec ustawiamy cechę Caption etykiety (Label1) na ten znak. Dla przykładu:

znak := #66;

przypisze zmiennej znak typu Char wartość 'B'. Natomiast ten sam efek uzyskamy tak:
znak := Char(66);

 

TYPY ŁAŃCUCHOWE 

Jednym z najczęściej używanych typów łańcuchowych jest typ String. Jest to bardzo pożyteczne rozwinięcie typu znakowego Char, ponieważ może zawierać o wiele większą liczbę znaków.

Typ Maks. dł. łańcucha Typ znaków Czy zakończony zerem
ShortString 255 ANSIChar Nie
AnsiString ~3 GB ANSIChar Tak
String 255 lub ~3 GB ANSIChar Tak lub Nie
WideString ~1.5 GB WideChar Tak

Delphi 3 jest w stanie obsługiwać znacznie dłuższe łańcuchy, niż w Delphi 1, w której łańcuchy miały maksymalną długość 255 znaków. Za obsługę łańcuchów o nieskończonej długości, bo tak należy rozumieć granicę ~3 GB, odpowiedzialna jest dyrektywa kompilatora {$H+} (jest to ustawienie domyślne). Może się wydać, że pozostałe typy łańcuchowe są niepotrzebne, ale firma Borland wiedziała co robi, bo pozwalają one zachować zgodność z poprzednimi wersjami Delphi. Dawny typ String domyślnie odpowiada typowi AnsiString (gdy włączymy H+). łańcuchy tego typu są zakończone zerem (null-terminated string) i są domyślnie alokowane w pamięci. Jest to duża przewaga w stosunku do poprzednich wersji łańcuchów, które alokowane był w pamięci statycznie. Chodzi o to, że dzisiaj ilość zajmowanej przez łańcuch pamięci jest dostosowana do jego faktycznego rozmiaru, a nie zadeklarowanej długości. Łańcuchy zakończone znakiem 0 zapewniają nam zgodność z funkciami API, system Windows korzysta bowiem tylko z takiego ich rodzaju. Dawniej przed kożdym wywołaniem funkcji konieczna była konwersja. Z tego powodu komponenty biblioteki VCL korzystają obecnie z typu AnsiString. Zwiększa to ich wydajność i szybkość przeprowadzanych operacji.

Jeszcze dwa zdania o pełnej zgodności łańcuchów z poprzednimi wersjami Delphi. W Delphi 3 służy do tego celu typ statyczny ShortString. Możemy go używać nawet przy włączonej dyrektywie {$H+}. Oto przykład:

{$H+} {włączamy domyśle korzystanie z długich łańcuchów}

var
dlugi_lancuch:String
{ to będzie dynamiczny łańcuch zakończony zerem o praktycznie nieograniczonym rozmiarze dynamicznie alokowany w pamięci}
stary_lancuch: String[20];
{to będzie statyczny łańcuch nie zakończony zerem o rozmiarze do 255 znaków bo podaliśmu długość i Delphi3 traktuje go jako typ ShortString}

Oto prosty przykład, w którym wykonamy kilka operacji na łańcuchach. Możesz go pobrać stąd lub przygotować samemu wstawiając do formularza komponent Memo i przycisk, którego procedura OnClick wygląda tak:

procedure TForm1.Button1Click(Sender: TObject);
var
napis: string;
krotki_napis: string[5];
liczba: Integer;
begin
napis := 'Dosyć dłuuuuuuuuuuuuuuugi łańcuch';
Memo1.Lines.Add('Wartość zmiennej napis: ' + napis);

krotki_napis := napis;
Memo1.Lines.Add('Wartość zmiennej krotki_napis: ' +krotki_napis);

liczba := 123456789;
napis := IntToStr(liczba);
Memo1.Lines.Add('Wartość zmiennej napis: '+napis);

napis :='';
Memo1.Lines.Add('A teraz zmienna napis jest pusta');
Memo1.Lines.Add('Wartość zmiennej napis: ' + napis)
end;

Na początek deklarujemy dwie zmienne napis typu String oraz krotki_napis typu ShortString i zmienną liczba. Dzieje się tak, ponieważ ustawiliśmy długość zmiennej krotki_napis na 5 znaków, a wtedy Delphi3 traktuje tę zmienną jako ShortString. W pierwszej linii przypisujemy zmiennej napis wartość 'Dosyć dłuuuuuuuuuuuuuuugi łańcuch', a następnie wypisujemy ją w Memo. Następnie podstawiamy zmienną napis do zmiennej krotki_napis i jej wartość wypisujemy w Memo. Dlaczego jej wartość to tylko 'Dosyć'? Odpowiedź tkwi w deklaracji zmiennej napis. Jej długość została ustawiona na 5 znaków i dlatego reszta została obcięta. Dalej przypisujemy zmiennej liczba wartość 123456789 i po konwersji z Integer na String podstawiamy do zmiennej napis. Na koniec ustawiamy wartość zmiennej napis na pustą (dwa apostrofy jeden po drugim).

W następnym numerze omówimy:
- typy złożone
- operatory

Kurs udostępnił Michał Lisowski
Object Pascal - strona o programowaniu w Delphi i Pascalu.