Turbo Pascal 7.0 - Elementy języka
Symbole |
Łańcuchy |
Komentarze |
Identyfikatory |
Liczby |
Typy danych |
Parametry funkcji i procedur |
Instrukcja |
Operatory |
Wyrażenia |
Symbole Turbo Pascal używa następujących podzbiorów znaków ze zbioru ASCII:
Cyfry heksalne (szesnastkowe) zapisywane są przy użyciu cyfr dziesiętnych i liter od A do F lub od a do f. Symbole specjalne są znakami, które w TP mają jedno lub kilka ustalonych znaczeń. Należą do nich następujące znaki: + - * / = < > [ ] . , ( ) : ; ' ^ @ { } $ # . Ponadto specjalnymi symbolami są następujące pary znaków: <= >= := .. (* *) (. .) Lewy nawias [ jest równoważny (., a prawy nawias ] parze .), ponadto { odpowiada (* a } odpowiada *). Łańcuchy Łańcuch jest ciągiem składającym się z zera lub więcej znaków z rozszerzonego zestawu kodu ASCII pisanym w jednej linii i zamkniętym w apostrofy. Łańcuch, który nie zawiera żadnych znaków między apostrofami nazywany jest łańcuchem zerowym (null string). Dwa kolejne apostrofy wewnątrz łańcucha oznaczają pojedyńczy apostrof. Przykłady łańcuchów:Turbo Pascal pozwala dodatkowo na umieszczanie w łańcuchach znaków sterujących. Znak # z liczbą całkowitą z zakresu [0,255] umieszczoną po nim oznacza odpowiednią wartość kodu ASCII, przy czym po znaku # nie może być spacji. Podobnie, jeżeli w łańcuchu umieszczone są dwa znaki sterujące, nie może być spacji między nimi. Np: #13#10 'Linia 1'#13'Linia 2' #7#7 ' Dzwiek'#7#7. Długością łańcucha jest rzeczywista liczba zawarta w nim znaków w danym momencie. Łańcuch znaków o dowolnej długości jest kompatybilny z jakimkolwiek typem łańcuchowym, a także z typem Pchar, jeżeli jest włączona składnia rozszerzona (dyrektywa {$X+}). Również łańcuch o długości 1 jest kompatybilny z typem Char, ponadto łańcuch o długości N jest kompatybilny ze znakową tablicą spakowaną (packed array). Komentarze Komentarze są dowolnymi łańcuchami tekstu ignorowanymi przez kompilator. Komentarz może być utworzony z użyciem nawiasów klamrowych np. { Tekst komentarza 1}albo też par symboli (* i *), np. (* Tekst komentarza 2*) Komentarz, w którym pierwszym znakiem jest znak dolara ($), jest tzw. dyrektywą kompilatora. Po znaku tym umieszcza się mnemonik danej dyrektywy. Identyfikatory Identyfikatory (nazwy) służą w Turbo Pascalu do oznaczania stałych, typów, zmiennych, słów kluczowych, procedur, funkcji, modułów (units), obiektów, programów i pól w rekordach. Identyfikator składa się z ciągu liter, cyfr i znaków podkreślenia. Identyfikator może mieć dowolną długość, lecz tylko pierwsze 63 znaki są znaczące (uwzględniane przez kompilator). Ponadto linia w TP może zawierać maksymalnie 126 znaków. Pierwszym znakiem identyfikatora musi być litera lub znak podkreślenia. Kolejne znaki identyfikatora mogą być literami, cyframi lub znakami podkreślenia. Małe i duże litery nie są rozróżniane. W sytuacji, gdy może się pojawić kilka wystąpień tego samego identyfikatora, może zaistnieć konieczność tzw. kwalifikacji danego identyfikatora przez inny identyfikator np.: W TP 7.0 występują dwie zasadnicze grupy identyfikatorów:
Identyfikatory standardowe to identyfikatory zdefiniowane przez twórców kompilatora, np: Real, Integer, clrscr itp. Ich znaczenie może być zmienione przez użytkownika (np. poprzez deklarację), wtedy ich pierwotne znaczenie nie jest bezpośrednio dostępne (jest przesłaniane). Aby użyć ich w znaczeniu pierwotnym należy zastosować identyfikator kwalifikowany. Do specjalnej kategorii nazw należą słowa kluczowe (keywords) i dyrektywy standardowe. Słowa kluczowe mogą być używane tylko w kontekscie określonym przez gramatykę TP i ich znaczenie nie może być zmieniane. TP 7.0 używa następujących słów kluczowych: and file not then array for object to asm function of type begin goto or unit case if packed until const implementation procedure uses constructor in program var destructor inherited record while div inline repeat with do interface set xor downto label shl else mod shr end nil string Dodatkowo TP 7.0 posiada następujące dyrektywy standardowe: absolute far near virtual assembler forward private external interrupt public Dyrektywy te mogą być stosowane tylko w kontekstach, w których nie może wystąpić identyfikator definiowany przez użytkownika. Mogą być one przedefiniowywane, lecz nie jest to zalecane. Dyrektywy private i public wewnątrz typów obiektowych funkcjonują jako słowa kluczowe. Liczby Przy zapisie liczb stosuje się zwykłą notację dziesiętną do zapisu stałych typów całkowitych i rzeczywistych. Zapis stałych całkowitych w postaci heksadecymalnej (szesnastkowej) wymaga użycia znaku $ (znak dolara) przed liczbą (np. $AF, $B0). Do zapisu liczb można też stosować tzw. notację naukową, gdzie liczbę zapisuje się w postaci mantysy i potęgi liczby 10, przy czym do oznaczenia 10 stosuje się litery e lub E (np. zapisuje się 8E-4, 8e-4, 16.25E+8 lub 16.25+e8). Liczby zapisywane z miejscami dziesiętnymi lub wykładnikiem (e lub E) są stałymi typu rzeczywistego. Inne liczby dziesiętne są stałymi całkowitymi. Muszą się one miescić w zakresie od -2 147 483 648 do 2 147 483 647. Liczby szesnastkowe z zakresu 0 do $7FFF reprezentować mogą stałe typu Integer, natomiast z zakresu od $00000000 do $FFFFFFFF stałe typu Longint. Znak stałej szesnastkowej typu Longint wynika z wartości liczby. Stałe z zakresu (0 , $7FFFFFFF) odpowiadają liczbom od 0 do 2 147 486 347, a z zakresu ($80000000 , $FFFFFFFF) liczbom od -2 147 483 648 do -1. Typy danych Typ danych określa wartości, które mogą przybierać elementy danego typu oraz operacje, które mogą być na nich wykonywane. Typy proste Typ całkowity Typ całkowity stanowi podzbiór zbioru liczb całkowitych. Wszystkie typy całkowite są typami porządkowymi.
Przykłady: Typ logiczny Zmienne typu logicznego (boolean) mogą posiadać tylko dwie wartości: TRUE i FALSE. Typy logiczne są także typami porządkowymi. Definicje stałych i zmiennych logicznych: const on: boolean = TRUE; off: boolean = FALSE; b1 = TRUE; b2 = FALSE; var koniec: boolean; Typ wyliczeniowy Składa się z uporządkowanego łańcucha wyliczanych elementów, np: type dni_rob = (pon, wto, sro, czw, pia); Każdemu z elementów łańcucha przypisuje się kolejną liczbę naturalną, począwszy od zera dla pierwszego wyliczanego elementu. Typ okrojony Niestandardowy typ porządkowy, stanowiący podzbiór pewnego typu danych (np. zbioru ASCII czy też zbioru liczb całkowitych), np.: Typ rzeczywisty Typ ten stanowią liczby rzeczywiste będące pewnym podzbiorem zbioru liczb rzeczywistych.
Wszystkie typy rzeczywiste poza real są dostępne tylko na komputerze z koprocesorem matematycznym albo przy włączonej programowej emulacji koprocesora (dyrektywa {$N+,$E+}). Przykłady: const min: real = 0.001; max: = 0.250; var wart_poj: real; Typ znakowy Dane tego typu są elementami zbioru zawierającego znaki rozszerzonego kodu ASCII. Przykłady: const ch = 'A'; const znak: char = '+'. , var zn: char; Typ łancuchowy Wartość typu string jest sekwencją pewnej liczby znaków. Zmienna typu string może przechowywać od 0 do 255 znaków. Przy deklaracji string [wymiar_lan], gdzie wymiar_lan może się zmieniać między 0 a 255, zmienna taka może w każdym momencie realizacji programu zawierać od zera do wymiar_lan znaków. W zerowym bajcie danej zmiennej łańcuchowej przechowywana jest, zakodowana w postaci znaku, aktualna długość zmiennej. Może być ona określona przy użyciu funkcji standardowej ord: l := ord(s[0]);lub też funkcji length: l := length(s);gdzie s jest nazwą danej zmiennej łańcuchowej. Przykłady: Typy wskaźnikowe Typ wskaźnikowy definiuje zbior wartości, które wskazują na zmienne dynamiczne wyspecyfikowanego typu zwanego typem bazowym. Zmienna typu wskaźnikowego zawiera adres obszaru pamieci operacyjnej, gdzie znajduje się zmienna dynamiczna. Przykłady: Jeżeli nazwa typu bazowego jest niezadeklarowanym identyfikatorem, to musi on być zadeklarowany w tej samej sekcji var co typ wskaźnikowy wskazujący na dany typ bazowy. Zmiennej typu wskaźnikowego można przypisać wartość przy użyciu:
Typ Pointer Predefiniowany typ Pointer jest typem wskaźnikowym nie wskazującym na żaden konkretny typ. Nie zawiera on informacji o wskazywanym obiekcie. Zmiennych typu Pointer nie można użyć bezpośrednio do odwołania się do konkretnego obiektu. Konieczne jest wcześniejsze dokonanie operacji rzutowania na określony typ. Np.: wyrażenie Ptr($40,$49) jest wyrażeniem wskazującym na obiekt o adresie $40:$49 czyli o wartości segmentu równej $40 i przesunięcia $49. Aby użyć wartości wskazywanej należy najpierw dokonać rzutowania (typecast), np. Po dereferencji wskaźnika typu Pointer zwracanego przez funkcję Ptr, zwracana wartość jest rzutowana na typ Byte.Wartości typu Pointer są zgodne w sensie przypisania ze wszystkimi innymi typami wskaźnikowymi. Typ PChar Typ PChar jest typem predefiniowanym do reprezentowania wskaźników do łańcuchów znakowych zakończonych znakiem #0 (ASCII 0). Łańcuchy tego typu mogą mieć do 65535 znaków. Jest on zdefiniowany w module System w sposób następujący type PChar= ^ Char; Typy strukturalne Typ tablicowy Typ tablicowy to typ strukturalny o ustalonej liczbie elementów tego samego typu. Deklaracja typu: type lista_ocen = array[1..liczba_elementow] of Integer; Typ indeksowy 1..liczba_elementow może być dowolnym typem porządkowym w wyjątkiem Longint i typów okrojonych typu Longint. Przykłady: Typ rekordowy Typ strukturalny, posiadający określoną liczbę składowych różnych typów nazywanych polami. Niektóre pola mogą być również typu rekordowego. Przykłady: type artykul = record nr_art: longint; nazwa_art: string[25]; cena_art: real; ilosc: integer; end; Typ rekordowy, w którym niektóre pola są typu rekordowego zwany jest typem eekordowym zagnieżdżonym, np.: type data = record dzien: byte; miesiac: byte; rok: word; end; type artykul = record nr_art: longint; nazwa_art: string[25]; cena_art: real; ilosc: integer; data_dostawy: data end; Istnieje również możliwość zdefiniowania typu rekordowego z wariantami, np.: type artykul = record nr_art: longint; nazwa_art: string[25]; cena_art: real; ilosc: integer; data_prod: data; case krajowy: boolean of TRUE: ( producent: string[25]); FALSE: (kraj_poch: string[25]; data_wwozu: data) end; Pole rekordu występujące po słowie kluczowym case zwane jest polem wyboru. Służy do wyboru struktury części wariantowej danej zmiennej rekordowej. Deklaracja zmiennych: var art_sklad: artykul; magazyn: array[1..1000] of artykul; Typ plikowy Typ strukturalny składający z elementów tego samego typu, który nazywany jest typem bazowym pliku (w Pascalu rozróżniamy typ plikowy elementowy, blokowy i tekstowy). Typ bazowy typu plikowego elementowego może być każdym typem z wyjątkiem typu plikowego, typu strukturalnego zawierającego typ plikowy lub typ obiektowy. Pliki blokowe są niskopoziomowymi kanałami stosowanymi do bezpośredniego dostępu do pliku dyskowego niezależnie od jego wewnętrznego formatu. Pliki tekstowe to pliki zawierające znaki zorganizowane w wiersze. Przykład. Typ zbiorowy Elementy tego typu to wszystkie podzbiory danego typu porządkowego bazowego włączając w to zbiór pusty. Zbiór bazowy może posiadać co najwyżej 256 elementów, a liczby porządkowe dolnej i górnej wartości zbioru bazowego muszą być w zakresie [0,255]. Zmienna typu zbiorowego może przechowywać od 0 do wszystkich możliwych elementów. Przykłady: type cyfry = set of '0'..'9' ; type male_litery = set of 'a'..'z' ; type wielkie litery = set of 'A'..'Z' ; Parametry funkcji i procedur W TP wyróżniamy parametry przekazywane przez wartość, parametry przekazywane przez zmienną, parametry stałe oraz parametry otwarte. Parametry przekazywane przez wartość Po powrocie z podprogramu parametry aktualne odpowiadające parametrom formalnym przekazywanym mają wartość taką jak przed ich użyciem w danym podprogramie. W tym przypadku przy wywoływaniu podprogramu tworzona jest kopia parametrów aktualnych i podprogram działa na tych kopiach, a nie na oryginalnych parametrach. Przykład: Parametry przekazywane przez zmienną W nagłówkach podprogramów deklaracji poprzedzone są one słowem kluczowym var. Zmienne przekazane do podprogramu i przez ten podprogram zmienione, zostaną zmienione również w programie głównym lub podprogramie wywołującym dany podprogram. W tym przypadku do podprogramu przekazywany jest adres odpowiedniego parametru aktualnego. Mechanizm ten jest podstawowym sposobem przekazywania rezultatów działania procedury do otoczenia, w ktorym została wywołana. Przykład: Parametry stałe Używa się ich w sytuacji, gdy podczas działania podprogramu nie ulegają zmianie. W deklaracji nazwę parametru poprzedzamy słowem const. Przykład: procedure testuj(const tekst: string); Parametry otwarte Umożliwiają przesłanie do podprogramu tablic i łańcuchów o różnych rozmiarach. Stosowanie ich umożliwia dyrektywa {$P+}. Przykład: Instrukcja Instrukcja przypisania Za pomocą tej instrukcji nadajemy zmiennej nową wartość. Przykład: a := 5; znak := 'A'; lancuch := 'Halo'; Instrukcja wywołania procedury Wywołanie procedury następuje poprzez podanie jej nazwy i opcjonalnie listy parametrów. Przykład: Instrukcja złożona (grupowania) Instrukcja złożona zaczyna się od słowa begin, a kończy słowem end. Między tymi słowami kluczowymi może się znajdować pewna liczba instrukcji. Stosuje się ją wszędzie tam, gdzie Pascal oczekuje instrukcji pojedynczej, podczas gdy jest konieczne wykonanie większej liczby instrukcji. Przykład: begin readln(a, b); oblicz (a, b); end; Instrukcje warunkowe: Instrukcje warunkowe służą do sterowania przebiegiem programu w zależności od spełnienia pewnych warunków. Instrukcja if Instrukcja ta ma dwie formy : if then i if then else. Forma pierwsza ma następującą składnię: Instrukcja występująca po if jest wykonywana tylko wtedy, gdy wyrażenie logiczne podane po if ma wartość logiczną TRUE (prawda - warunek jest spełniony). Forma druga: W tym przypadku, jeżeli wyrażenie po if ma wartość logiczną TRUE jest wykonywana instrukcja1, jeśli zaś wyrażenie po if ma wartość logiczną FALSE, to wykonywana jest instrukcja2. Przykład: if mian <> 0 then writeln (liczn div mian) else writeln ('Dzielenie przez 0'); Instrukcja case Instrukcja case jest instrukcją wyboru umożliwiającą wybór i realizację jednego z wielu wariantów. Instrukcja case składa się z słowa kluczowego case, wyrażenia (zwanego selektorem), słowa kluczowego of oraz listy instrukcji, z których każda poprzedzona jest jedną lub wieloma stałymi zwanymi stałymi wyboru. Instrukcja case może też zawierać klauzulę else. Selector musi być typu porządkowego. Wszystkie stałe muszą być unikalne (stała nie może się powtórzyć) i typu zgodnego z typem selektora. Instrukcja case wykonuje instrukcję poprzedzoną stałą rowną wartości selektora lub instrukcję poprzedzoną zakresem zawierającym daną wartość selektora. Jeżeli nie ma stałej ani zakresu zawierającego wartości równej wartości selektora, to jest wykonywana instrukcja po else. Jeśli nie ma else, to następuje przejście do kolejnej instrukcji po case. case wyrazenie of stala_1: instrukcja; stala_2: begin instrukcja; instrukcja end; ... stala_n: instrukcja; else instrukcja end; Przykład: Instrukcje pętli Instrukcje powtarzania umożliwiają wielokrotne wykonywanie pewnej liczby instrukcji. W Pascalu są trzy typy pętli:
Jeżeli liczba powtórzeń jest znana, stosuje się pętlę for, w przeciwnym przypadku pętlę repeat lub pętlę while. Do kontroli przebiegu pętli można stosować standardowe procedury Break i Continue. Procedura Break wywołana wewnątrz pętli powoduje zakończenie wykonywania pętli. Procedura Continue powoduje przerwanie bieżącej iteracji i rozpoczęcie wykonywania następnej iteracji. Instrukcja repeat Instrukcja ta ma następującą składnię: Wyrażenie po until musi być wyrażeniem logicznym. Instrukcje pomiędzy repeat i until są wykonywane tak długo, jak długo wyrażenie po until przybiera wartości logiczną FALSE. Instrukcje pętli są wykonywane przynajmniej 1 raz. Przykład: wartosc := 0; repeat Write(wartosc); Inc(wartosc); until wartosc = 10; Instrukcja while Prosta lub złożona instrukcja po while jest powtarzana dopóki wyrażenie po while ma wartość TRUE. while wyrazenie_logiczne do instrukcja; Przykład: wartosc := 0; while wartosc < l0 do begin Writeln(wartosc); Inc(wartosc); end; Instrukcja for Jest to pętla o określonej liczbie przebiegów. Po każdym przebiegu licznik pętli jest automatycznie zwiększany (przy downto - zmniejszany) o 1. Zmienna sterująca musi być zmienną bez jakichkolwiek kwalifikatorów, lokalną w bloku zawierającym daną instrukcję for. Ponadto zmienna sterująca musi być typu porządkowego. Wartość początkowa i wartość końcowa muszą być typu zgodnego w sensie przypisania z typem porządkowym. for zmienna_ster := start to stop do|downto instrukcja; W momencie rozpoczęcia realizacji instrukcji for są określane wartości początkowa i końcowa i są one określane tylko raz na początku przebiegu pętli. Instrukcja zawarta w pętli for jest wykonywana dla każdej wartości w zakresie od start do stop. Pierwszą wartością zmiennej sterującej (zmienna_ster) jest zawsze wartość start. W instrukcji for to wartość zmiennej sterującej jest zwiększana o 1 przy każdym powtórzeniu pętli. Jeśli start jest większa od stop, to instrukcja po do nie jest wykonywana. W instrukcji for downto wartość zmiennej sterującej jest zmniejszana o 1 przy każdym powtórzeniu pętli. Jeżeli w tym przypadku start jest mniejsza od stop, to instrukcja po downto nie jest wykonywana. Jeśli instrukcja po do lub downto zmienia wartość zmiennej sterującej, to rezultat działania pętli jest trudny do określenia. Po zrealizowaniu pętli for wartość zmiennej sterującej jest nieokreślona. Przykłady: for wartosc := 1 to 10 do Writeln (wartosc); for wartosc := 10 downto 1 do Writeln(wartosc); Instrukcja with Instrukcja ta ułatwia dostęp do pól rekordu. Można wewnątrz niej stosować tylko identyfikator pola rekordu zamiast pełnej nazwy. Np.: dana jest zmienna rekordowa artykul posiadająca pola numer, nazwa i cena. Stosując with można zastosować skrócone odwołania do pól zmiennej rekordowej artykul: with artykul do { rekord 'artykul' } begin numer := 100; { pole 'numer' } nazwa := 'CD-RW'; { pole 'nazwa' } cena := 8800; { pole 'cena' } end; Operatory Operatory arytmetyczne
Operatory relacji Operatory te porównują ze sobą dwa wyrażenia i dostarczają wynik typu logicznego (boolean) tzn. TRUE (prawdę) lub FALSE(fałsz).
Operatory boolowskie Dla tych operatorów operandy muszą być typu boolean, a wynik również zawsze zwraca wartość typu boolean (TRUE lub FALSE).
Operatory logiczne (bitowe) Dla tych operatorów operandy muszą być typu całkowitego, a wynik również zawsze liczbę całkowitą.
Operator łańcuchowy
Wyrażenia Wyrażenia w TP składają się z operatorów i operandów. Operandami mogą być stałe, zmienne i funkcje. W przypadku bardziej złożonych wyrażeń i występowania większej liczby operatorów, istnieją w Pascalu reguły określające kolejności wykonania poszczególnych operatorów. Reguły te nazywane są priorytetami operatorów. Poniżej przedstawiono je w tabeli:
Fragmenty wyrażenia można zamykać w nawiasy, aby zmienic kolejność wykonywania operacji w wyrażeniach. Istnieją 3 reguły pierwszeństwa:
|