PODSTAWY PROGRAMOWANIA Andrzej Marciniak Prezentacja multimedialna przygotowana za pomocą systemu Corel Presentations X3 Copyright 2003-2017 by Andrzej Marciniak PP-6(1 z 82)
Na poprzednim wykładzie... P typy danych i ich opis (typy opisujące obiekty, typy wskaźnikowe, proceduralne, wariantowe, zagnieżdżone definicje typów, zgodność typów) Pzmienne (deklaracje zmiennych, zmienne ideksowane, rekordowe, obiektowe, dynamiczne, proceduralne, wariantowe, wątkowe, z początkową wartością, nakładanie zmiennych, literały stałe i zmienne) PP-6(2 z 82)
Na tym wykładzie... P wyrażenia rodzaje operatorów i ich priorytet składnia wyrażenia wyrażenia stałe przeciążanie operatorów P instrukcje instrukcje proste (przypisania, skoku i pusta) instrukcje strukturalne (złożona i warunkowe) PP-6(3 z 82)
Wyrażenie jest zapisem algorytmu określającego sposób obliczania pewnej wartości i składa się z sensownej kombinacji operatorów i argumentów (operandów), które same mogą być też wyrażeniami. Wyrażenie nie stanowi samoistnej instrukcji języka Delphi, a jedynie jest jej częścią składową. PP-6(4 z 82)
Operatory dzielimy na: Parytmetyczne, P logiczne, P relacyjne, P teoriomnogościowe, P operator konkatenacji, P wariantowe, P operator @, P wskaźników znaków (pomijamy), PP-6(5 z 82) P odwołań do klas i obiektów.
Priorytet operatorów W celu jednoznacznego przypisania argumentów do operatorów, a tym samym wykonania obliczeń w pożądanej kolejności, stosuje się nawiasy okrągłe. W przypadku braku odpowiednich nawiasów kolejność wykonywania obliczeń jest ustalona przez priorytet operatorów. Obowiązują przy tym następujące zasady: P argument występujący pomiędzy dwoma operatorami o różnych priorytetach jest związany z operatorem o wyższym priorytecie, P argument znajdujący się między dwoma operatorami o tym samym priorytecie jest związany z operatorem z lewej strony, P wyrażenia występujące w nawiasach (okrągłych) są wykonywane przed użyciem ich jako pojedynczego argumentu. Operacje z równymi priorytetami są wykonywane od strony lewej do prawej (?). PP-6(6 z 82)
Priorytet operatorów Operatory Priorytet Kategoria operatorów +,, @, not 1 (najwyższy) jednoargumentowe *, /, div, 2 multiplikatywne mod, and, shl, shr, as +,, or, xor 3 addytywne =, <>, <, >, 4 (najniższy) relacyjne <=, >=, in, is PP-6(7 z 82)
Składnia wyrażenia W ogólności wyrażenie jest zbudowane z czynników, składników i wyrażeń prostych. Czynnik jest to: P odwołanie do zmiennej, P odwołanie do zmiennej poprzedzone operatorem @, P nazwa funkcji lub procedury poprzedzona operatorem @, P kwalifikowana nazwa metody poprzedzona znakiem @, P stała bez znaku, P wywołanie funkcji, P konstruktor zbioru, P zmiana typu wyrażenia, P czynnik poprzedzony znakiem + (plus), (minus) lub operatorem not, P wyrażenie ujęte w nawiasy okrągłe. PP-6(8 z 82)
Składnia wyrażenia Przykłady a odwołanie do zmiennej @a odwołanie do zmiennej poprzedzone operatorem @ 123 stała bez znaku (liczba bez znaku) 123 stała bez znaku (łańcuch) Sin(x) wywołanie funkcji [ 0.. 9, a.. b ] konstruktor zbioru Integer(x+123) zmiana typu wyrażenia 123 czynnik poprzedzony znakiem (minus) not a czynnik poprzedzony operatorem not (a+b+c) wyrażenie ujęte w nawiasy okrągłe PP-6(9 z 82)
Składnia wyrażenia Składnikiem nazywamy czynnik lub połączenie dwu lub większej liczby czynników operatorem multiplikatywnym (*, /, div, mod, and, shl, shr, as). Przykłady a*b a/(b 2) (x+y) div z (a<b) and (x>=y) alpha shl beta PP-6(10 z 82)
Składnia wyrażenia Wyrażenie proste jest to składnik lub połączenie dwu lub większej liczby składników operatorem addytywnym (+,, or, xor). Przykłady x a+b x*y+c PP-6(11 z 82)
Składnia wyrażenia Wyrażeniem nazywamy wyrażenie proste lub połączenie dwu wyrażeń prostych operatorem relacyjnym (<, <=, =, >, >=, <>, in, is). Przykłady (a+b)<1.5 (alpha>beta)<>gamma x in zbior nadawca is TButton PP-6(12 z 82)
Operatory arytmetyczne Stosuje się je do obliczania wartości liczbowych. Operator Operacja Typ argumentów Typ wyniku + (jednoarg.) identyczność całkowity Integer lub Int64 rzeczywisty Extended (jednoarg.) zmiana znaku całkowity Integer lub Int64 rzeczywisty Extended + dodawanie całkowity Integer lub Int64 rzeczywisty Extended odejmowanie całkowity Integer lub Int64 rzeczywisty Extended PP-6(13 z 82)
Operatory arytmetyczne Stosuje się je do obliczania wartości liczbowych. Operator Operacja Typ argumentów Typ wyniku * mnożenie całkowity Integer lub Int64 rzeczywisty Extended / dzielenie całkowity Extended rzeczywisty Extended div dzielenie całkowity Integer lub Int64 całkowite mod reszta całkowity Integer lub Int64 z dzielenia PP-6(14 z 82)
Operatory arytmetyczne W języku Delphi nie występuje operator potęgowania. Kwadraty i pierwiastki oblicza się za pomocą funkcji standardowych Sqr i Sqrt. Podniesienie do potęgi całkowitej można zrealizować poprzez wielokrotne mnożenie lub za pomocą funkcji IntPower z modułu System.Math. W celu obliczenia dodatniej potęgi rzeczywistej liczby można zastosować w odpowiedni sposób na przykład funkcje standardowe Exp i Ln lub funkcję Power z modułu System.Math. PP-6(15 z 82)
Operatory arytmetyczne Uwaga! Wartość typu Int64 można otrzymać tylko w przypadku, gdy co najmniej jeden operand jest tego typu. Przypisanie wartości typu Integer do zmiennej typu Int64 może doprowadzić do otrzymania błędnego wyniku. Przykład Niech zmienne j oraz k będą zadeklarowane następująco: var j : Integer; k : Int64; W wyniku wykonania instrukcji j:=maxint; k:=j+1; otrzymamy niepoprawną wartość. Przypisanie właściwej wartości typu Int64 do zmiennej k nastąpi po wykonaniu instrukcji k:=int64(j)+1; PP-6(16 z 82)
Operatory logiczne Operatory te służą do wykonywania operacji logicznych na wartościach typów logicznych oraz na wartościach całkowitych. Operator Operacja Typ argumentów Typ wyniku not (jednoarg.) negacja całkowity całkowity logiczny Boolean and koniunkcja całkowity całkowity logiczny Boolean or alternatywa całkowity całkowity logiczny Boolean PP-6(17 z 82)
Operatory logiczne Operatory te służą do wykonywania operacji logicznych na wartościach typów logicznych oraz na wartościach całkowitych. Operator Operacja Typ argumentów Typ wyniku xor różnica całkowity całkowity symetryczna logiczny Boolean shl przesunięciecałkowity całkowity w lewo shr przesunięciecałkowity całkowity w prawo PP-6(18 z 82)
Operatory logiczne Uwaga! Jeżeli obydwa argumenty operatora and, or lub xor są różnych typów całkowitych, to typem wyniku jest predefiniowany typ całkowity o najmniejszym zakresie, w którym są zawarte wszystkie wartości typów obu argumentów. Jeżeli operandy operatora logicznego są typów logicznych, to wynik jest określony tak, jak w logice matematycznej. Operacje logiczne na operandach typów całkowitych są operacjami wykonywanymi na odpowiednich bitach operandów. Negacja operandu typu całkowitego polega na zamianie każdego bitu reprezentacji danej w pamięci na przeciwny, tj. bitu 0 na 1, a bitu 1 na 0. Dotyczy to także bitu znaku. PP-6(19 z 82)
Operatory logiczne Przykład Niech zmienne w oraz sh będą zadeklarowane następująco: var w : Word = 1000; sh : Shortint = 100; Jaka jest wartość wyrażenia w or sh? Typem o najmniejszym zakresie zawierającym wszystkie wartości typów argumentów jest typ Integer. Zatem najpierw zostaną wykonane konwersje: 1000 (10) = 0000001111101000 (2) : 00000000000000000000001111101000 (2) 100 (10) = 10011100 (2) : 11111111111111111111111110011100 (2). dwójkowa arytmetyka uzupełnieniowa 100 (10) = 01100100 (2) = (zamiana) 10011011 (2) + 1 (2) PP-6(20 z 82)
Przykład Operatory logiczne Niech zmienne w oraz sh będą zadeklarowane następująco: var w : Word = 1000; sh : Shortint = 100; Jaka jest wartość wyrażenia w or sh? Następnie jest wykonywana operacja alternatywy na odpowiadających sobie bitach: 00000000000000000000001111101000 (2) or 11111111111111111111111110011100 (2) 11111111111111111111111111111100 (2) PP-6(21 z 82)
Przykład Operatory logiczne Niech zmienne w oraz sh będą zadeklarowane następująco: var w : Word = 1000; sh : Shortint = 100; Jaka jest wartość wyrażenia w or sh? Pierwszy bit (1) wskazuje, że otrzymaliśmy liczbę ujemną. Zamieniając na pozostałych bitach cyfry 0 na 1, a cyfry 1 na 0, a następnie dodając jedynkę dwójkową otrzymujemy (przejście do zwykłego zapisu dwójkowego) 0000000000000000000000000000100 (2), a więc w zapisie dziesiętnym mamy 4. PP-6(22 z 82)
Operatory logiczne Operacje logiczne shl (przesunięcie w lewo) i shr (przesunięcie w prawo) mogą dotyczyć wyłącznie argumentów typu całkowitego. Wynik operacji jest wartością uzyskaną z reprezentacji pierwszego argumentu po przesunięciu go w lewo (shl) lub w prawo (shr) o liczbę pozycji określoną drugim argumentem. Podczas przesuwania bit znaku nie ulega powieleniu, a zwolnione pozycje zapełniane są bitami o wartości 0. PP-6(23 z 82)
Przykłady Operatory logiczne wyrażenie wartość wyrażenie wartość 1 shl 7 128 1 shr 7 0 1 shl 30 1073741824 1 shr 30 0 1 shl 31 2147483648 1 shr 31 0 1 shl 32 1 1 shr 32 1 1 shl 62 1073741824 1 shr 62 0 1 shl 63 2147483648 1 shr 63 0 1 shl 64 1 1 shr 64 1 1 shl 255 2 1 shr 255 0 3 shl 5 96 3 shr 5 134217727 PP-6(24 z 82)
Operatory relacyjne Operatory relacyjne (dwuargumentowe) służą do konstrukcji wyrażeń porównania. Operatorami tymi są: = równy <> nierówny < mniejszy > większy <= nie większy lub jest zawarty, >= nie mniejszy lub zawiera, in jest elementem. Wynik wyrażenia porównania jest typu Boolean i ma wartość logiczną True, gdy relacja jest prawdziwa lub wartość False, gdy relacja jest fałszywa. PP-6(25 z 82)
Operatory relacyjne W zależności od typu argumentów relacje dzielimy na: P arytmetyczne (w tym logiczne), P łańcuchowe (w tym znakowe), P teoriomnogościowe, P wskaźnikowe (w tym działań na klasach, łączach programowych i odwołaniach do klas), P wariantowe. PP-6(26 z 82)
Relacje arytmetyczne oczywiste. Operatory relacyjne Porównanie łańcuchowe występuje wtedy, gdy oba argumenty są typu łańcuchowego, znakowego (Char, AnsiChar, WideChar) lub upakowanego typu łańcuchowego (jednowymiarową tablicą znaków). Nie wymaga się przy tym, aby argumenty te musiały być identycznych typów. Podczas porównywania wartości typu znakowego z wartością typu łańcuchowego pierwsza z nich jest uważana za wartość typu łańcuchowego o długości 1. PP-6(27 z 82)
Operatory relacyjne Porównanie zachodzi pomiędzy odpowiadającymi sobie znakami, zgodnie z ich uporządkowaniem w zestawie znaków Unicode. Dwa argumenty uważa się za równe, gdy składają się z identycznych znaków. Jeśli nie są równe i żaden nie składa się z pustego ciągu znaków, to relacja jest równoważna relacji pomiędzy pierwszymi różnymi i odpowiadającymi sobie znakami. Jeśli takie znaki nie istnieją, co występuje w przypadku, gdy jeden ciąg znaków jest podciągiem drugiego, to za mniejszy uważa się argument składający się z mniejszej liczby znaków. Pusty ciąg znaków jest mniejszy od każdego innego ciągu. PP-6(28 z 82)
Operatory relacyjne Przykłady wyrażenie ABC > ABD ABC < ABD ABC = abc ABC <= abc + <= wynik False True False True True 01 = 1 False PP-6(29 z 82)
Operatory relacyjne Na operandach a i b typu zbiorowego można wykonywać następujące operacje porównania (porównania teoriomnogościowe): a = b a <> b a <= b a >= b c in a równość zbiorów (relacja prawdziwa, jeśli zbiory a i b zawierają te same elementy), różność zbiorów (relacja prawdziwa, gdy zbiory a i b są zbiorami różnych elementów), zawieranie zbioru a w zbiorze b (relacja prawdziwa, gdy każdy element zbioru a jest także elementem zbioru b), zawieranie zbioru b w zbiorze a (relacja prawdziwa, gdy każdy element zbioru b jest także elementem zbioru a), sprawdzenie, czy element c typu porządkowego jest elementem zbioru a (typem bazowym zbioru a musi być PP-6(30 z 82) typ zgodny z typem elementu c).
Przykłady Operatory relacyjne Załóżmy, że jest dany następujący opis: type dni_pracy = set of (poniedziałek, wtorek, środa, czwartek, piątek); var dni : dni_pracy; oraz instrukcja dni:=[poniedziałek.. piątek]; Wówczas: wyrażenie wynik dni=[poniedziałek..piątek] dni=[wtorek..czwartek] [wtorek..czwartek]<>dni [wtorek..czwartek]<=dni dni<=[wtorek..czwartek] wtorek in dni True False True True False True PP-6(31 z 82)
Operatory relacyjne Operandy typu wskaźnikowego mogą być porównywane (porównanie wskaźnikowe) wyłącznie za pomocą operatorów = ( równy ) i <> ( nierówny ). Dwa wskaźniki uważane są za równe, jeżeli oznaczają ten sam adres w pamięci. Za pomocą tych operatorów można także porównywać elementy typów klasowych i typów odwołań do klas. Dwa takie elementy uważa się za równe, gdy wskazują na ten sam obiekt (a więc gdy podobnie jak poprzednio wskazują ten sam adres w pamięci). PP-6(32 z 82)
P suma, P różnica, P iloczyn zbiorów. Operatory teoriomnogościowe Operacjami teoriomnogościowymi, które mogą być bezpośrednio zaprogramowane w języku Delphi Pascal za pomocą odpowiednich operatorów są: Operacje te są wykonywane na argumentach typu zbiorowego o zgodnych typach bazowych. PP-6(33 z 82)
Operatory teoriomnogościowe Operator Operacja Typ argumentów Typ wyniku + suma zbiorów zbiorowy zbiorowy o zgodnych typach bazowych różnica zbiorów * iloczyn zbiorów Przykłady wyrażenie wynik [2, 3, 4]+[4, 5, 6] [2, 3, 4, 5, 6] [2, 3, 4] [4, 5, 6] [2, 3] [2, 3, 4]*[4, 5, 6] [4] wyrażenie wynik [20..30]+[25..50] [20..50] [True, False] [ ] [True, False] [ a, c, e ] [ e ] [ a, c ] PP-6(34 z 82)
Konkatenacja Do połączenia dwu lub więcej łańcuchów w jeden łańcuch służy operator konkatenacji, zapisywany za pomocą znaku + (plus). Argumenty typu łańcuchowego, znakowego lub upakowanego typu łańcuchowego połączone tym operatorem tworzą wyrażenie konkatenacji. Typ wyniku zależy przy tym od typu operandów. Przykłady wyrażenie wynik Delphi + Pascal DelphiPascal Delphi + + Pascal Delphi Pascal 12 +.0 + E 1 12.0E 1 PP-6(35 z 82)
Operatory w wyrażeniach wariantowych Na elementach typów wariantowych mogą być wykonywane operacje określone operatorami +,, *, /, div, mod, not, and, or, xor, shl, shr, =, <>, <, >, <= oraz >=. Dla operatorów dwuargumentowych obowiązuje przy tym zasada, że jeśli jeden z argumentów jest typu Variant, to przed wykoniem operacji drugi argument jest automatycznie przekształcany na ten typ. Typem wyniku operacji nierelacyjnej (+,, *, /, div, mod, not, and, or, xor, shl i shr) jest zawsze Variant, a operacji relacyjnej (=, <>, <, >, <= i >=) Boolean. PP-6(36 z 82)
Operator @ Jednoargumentowy operator @ służy do utworzenia wskaźnika (adresu) podanego argumentu. Postać wyrażenia zawierającego operator @ jest następująca: @ argument przy czym wartość tego wyrażenia jest typu wskaźnikowego, a argument może być zmienną, nazwą funkcji lub procedury lub kwalifikowaną nazwą metody. PP-6(37 z 82)
Przykłady Operator @ Jeśli zmienne bajt i wsk_bajt będą zadeklarowane następująco: var bajt : Byte; wsk_bajt : ^Byte; to instrukcja przypisania wsk_bajt:=@bajt; spowoduje przypisanie zmiennej wsk_bajt adresu zmiennej bajt. PP-6(38 z 82)
Operator @ Przykłady Załóżmy, że w programie występuje definicja typu proceduralnego funkcja postaci: type funkcja = function : Integer; deklaracja zmiennej proceduralnej zm_funk: var zm_funk : funkcja; oraz definicja funkcji bezparametrowej alfa o wartości typu Integer. W celu sprawdzenia, czy aktualnie zmienna proceduralna zm_funk reprezentuje funkcję alfa należy sprawdzić, czy jest prawdziwe wyrażenie porównania @zm_funk=@alfa Zastosowanie do tego celu porównania zm_funk=alfa PP-6(39 z 82) jest błędne (dlaczego?).
Przykłady Operator @ W celu otrzymania adresu zmiennej proceduralnej z poprzedniego przykładu należy użyć wyrażenia @@zm_funk Wyrażenie @zm_funk określa bowiem adres funkcji, która jest aktualnie przypisana zmiennej zm_funk. PP-6(40 z 82)
Operatory odwołań do klas i obiektów Do wykonywania operacji na klasach i odwołaniach do klas służą operatory is i as. Operator is służy do sprawdzania typu obiektu podczas wykonywania programu, tzn. do określenia, czy dany obiekt (wartość zmiennej typu klasowego) jest aktualnie elementem pewnej klasy. Postać wyrażenia z operatorem is jest następująca: zmienna-typu-klasowego is odwołanie-do-klasy gdzie odwołanie do klasy jest identyfikatorem klasy lub zmienną typu odwołania do klasy. PP-6(41 z 82)
Operatory odwołań do klas i obiektów Wartością wyrażenia z operatorem is jest wartość logiczna True, gdy obiekt określony przez zmienną typu klasowego jest elementem klasy określonej przez odwołanie do klasy lub klasy z niej wyprowadzonej (potomnej). W przeciwnym przypadku wartością wyrażenia jest wartość logiczna False. Jeśli wartością zmiennej typu klasowego jest adres pusty (nil), to wartością wyrażenia jest zawsze False. Wyrażenie z operatorem is jest na ogół wykorzystywane w instrukcji warunkowej jeśli do zagwarantowania poprawności zmiany typu, na przykład if sterowanie is TEdit then TEdit(sterowanie).ClearSelection; PP-6(42 z 82)
Operatory odwołań do klas i obiektów Wyrażenie z operatorem as ma postać zmienna-typu-klasowego as odwołanie-do-klasy gdzie odwołanie do klasy ma takie samo znaczenie, jak poprzednio. Wyrażenie to pozwala zmienić typ wyspecyfikowanej zmiennej na typ określony drugim operandem, przy czym zmienna ta w dalszym ciągu będzie wskazywała ten sam obiekt w pamięci. Zmienna określająca obiekt musi mieć albo wartość nil, albo wskazywać na obiekt typu zdefiniowanego przez odwołanie do klasy, albo też na obiekt typu potomnego tej klasy. PP-6(43 z 82)
Operatory odwołań do klas i obiektów z operatorem as używa się zwykle w połączeniu z instrukcją wiążącą (będzie dalej) do skrócenia odwołań o zmienionym typie do pól, metod i własności. Przykład (nadawca as TButton).Caption:='&Ok'; (nadawca as TButton).OnClick:=OkClick; lub with nadawca as TButton do begin Caption:='&Ok'; OnClick:=OkClick end; Typ zmiennej nadawca musi być typem nadrzędnym, równym lub potomnym typu TButton. PP-6(44 z 82)
stałe Wyrażenie stałe jest to wyrażenie, które może być obliczone przez kompilator. Wyrażenie takie nie może zawierać zmiennych, literałów zmiennych, wskaźników, wywołań funkcji (z wyjątkiem funkcji wymienionych poniżej) oraz operatora adresowego @. W wyrażeniach stałych dozwolone jest stosowanie następujących funkcji standardowych: Abs High Low Pred Succ Chr Length Odd Round Swap Hi Lo Ord SizeOf Trunc PP-6(45 z 82)
Przykłady stałe 123*45.67 Abs( 98.765) (432 div 2) informa + tyka [ 0.. 9 ] + [ A.. Z, a.. z ] A +Chr(35) PP-6(46 z 82)
Zmiana typu wyrażenia Każde z przedstawionych wyrażeń daje w wyniku wartość określonego typu. Wartości wyrażeń typu porządkowego lub wskaźnikowego mogą być zmienione na wartości innego typu porządkowego lub wskaźnikowego. Do zmiany typu wyrażenia służy konstrukcja: identyfikator-typu (wyrażenie) przy czym typ wyrażenia i typ podany za pomocą identyfikatora typu muszą być jednocześnie albo typami porządkowymi, albo typami wskaźnikowymi. PP-6(47 z 82)
Zmiana typu wyrażenia Przykłady Integer( A ) Konstrukcja ta spowoduje zinterpretowanie wewnętrznego przedstawienia znaku A, tj. ciągu 01000001, jako liczby typu Integer. Wartością powyższego wyrażenia będzie zatem 65. Boolean(0) Liczba całkowita 0 zostanie zinterpretowana jako wartość logiczna False. PP-6(48 z 82)
Przeciążanie operatorów W obrębie definicji typów rekordowych można przeciążać pewne operatory, tj. spowodować ich działanie inne niż standardowe. Deklaracja operatora przeciążonego w typie rekordowym ma postać class operator sygnatura-deklaracyjna gdzie sygnatura deklaracyjna określa operator (operatory mają swoje nazwy), typy operandów i typ wyniku S zob. następne slajdy. Po definicji typu rekordowego z deklaracją operatora przeciążonego musi wystąpić definicja tego operatora. PP-6(49 z 82)
Przeciążanie operatorów sygnatura deklaracyjna oznaczenie symboliczne Implicit (a : typ) : typ-wyniku; niejawna zmiana typu Explicit (a : typ) : typ-wyniku; jawna zmiana typu Negative (a : typ) : typ-wyniku; Positive (a : typ) : typ-wyniku; + Inc (a : typ) : typ-wyniku; Inc (funkcja standardowa) Dec (a : typ) : typ-wyniku; Dec (funkcja standardowa) LogicalNot (a : typ) : typ-wyniku; not Trunc (a : typ) : typ-wyniku; Trunc (funkcja standardowa) Round (a : typ) : typ-wyniku; Round (funkcja standardowa) In (a : typ; b : typ) : Boolean; in Equal (a : typ; b : typ) : Boolean; = NotEqual (a : typ; b : typ) : Boolean; < > GreaterThan (a : typ; b : typ) : Boolean; > PP-6(50 z 82)
Przeciążanie operatorów sygnatura deklaracyjna oznaczenie symboliczne GreaterThanOrEqual (a : typ; b : typ) : Boolean; >= LessThan (a : typ; b : typ) : Boolean; < LessThanOrEqual (a : typ; b : typ) : Boolean; <= Add (a : typ; b : typ) : typ-wyniku; + Subtract (a : typ; b : typ) : typ-wyniku; Multiply (a : typ; b : typ) : typ-wyniku; * Divide (a : typ; b : typ) : typ-wyniku; / IntDevide (a : typ; b : typ) : typ-wyniku; div Modulus (a : typ; b : typ) : typ-wyniku; mod LeftShift (a : typ; b : typ) : typ-wyniku; shl RightShift (a : typ; b : typ) : typ-wyniku; shr LogicalAnd (a : typ; b : typ) : typ-wyniku; and LogicalOr (a : typ; b : typ) : typ-wyniku; or PP-6(51 z 82)
Przeciążanie operatorów sygnatura deklaracyjna LogicalXor (a : typ; b : typ) : typ-wyniku; BitwiseAnd (a : typ; b : typ) : typ-wyniku; BitwiseOr (a : typ; b : typ) : typ-wyniku; BitwiseXor (a : typ; b : typ) : typ-wyniku; oznaczenie symboliczne xor and or xor Definicja operatora przeciążonego powinna wystąpić po definicji typu rekordowego z jego deklaracją (w tej samej jednostce programowej). Jej postać jest podobna do definicji metody, tyle że rozpoczyna się od słów class operator. PP-6(52 z 82)
Przykład Przeciążanie operatorów type dod_mod5 = record var w : Integer; class operator Add (a, b : dod_mod5) : Integer; class operator Implicit (a : Integer) : dod_mod5; class operator Explicit (a : dod_mod5) : Integer; end; W definicji tej występują deklaracje trzech operatorów przeciążonych. Niech ich definicje będą następujące: class operator dod_m5.add (a, b : dod_m5) : dod_m5; begin Result:=a.w+b.w mod 5 end; PP-6(53 z 82)
Przykład Przeciążanie operatorów type dod_mod5 = record var w : Integer; class operator Add (a, b : dod_mod5) : Integer; class operator Implicit (a : Integer) : dod_mod5; class operator Explicit (a : dod_mod5) : Integer; end; W definicji tej występują deklaracje trzech operatorów przeciążonych. Niech ich definicje będą następujące: class operator dod_m5.implicit (a : Integer) : dod_m5; begin Result.w:=a end; PP-6(54 z 82)
Przykład Przeciążanie operatorów type dod_mod5 = record var w : Integer; class operator Add (a, b : dod_mod5) : Integer; class operator Implicit (a : Integer) : dod_mod5; class operator Explicit (a : dod_mod5) : Integer; end; W definicji tej występują deklaracje trzech operatorów przeciążonych. Niech ich definicje będą następujące: class operator dod_m5.explicit (a : dod_m5) : Integer; begin Result:=a.w end; PP-6(55 z 82)
Przykład Jeśli dalej zadeklarujemy zmienne: Przeciążanie operatorów var x, y : dod_m5; a, b : Integer; to wykonanie (w programie tekstowym) instrukcji: a:=20; b:=12; Writeln (a+b mod 5); x:=a; y:=b; niejawna zmiana typu z Integer Writeln (x+y); na dod_m5 spowoduje pojawienie się na ekranie napisów: 22 22 PP-6(56 z 82)
Przykład Deklaracje zmiennych: var x, y : dod_m5; a, b : Integer; Instrukcje: a:=20; b:=12; Writeln (a+b mod 5); x:=a; y:=b; Writeln (x+y); Przeciążanie operatorów Gdyby nie zdefiniowano operatora Implicit (niejawnej zmiany typu), to instrukcje te trzeba by zastąpić instrukcjami: x.w:=a; y.w:=b; PP-6(57 z 82)
Przykład Deklaracje zmiennych: var x, y : dod_m5; a, b : Integer; Instrukcje: a:=20; b:=12; Writeln (a+b mod 5); x:=a; y:=b; Writeln (x+y); Przeciążanie operatorów Operator Explicit (jawnej zmiany typu) może być wykorzystany np. w instrukcjach: Writeln (Integer(x)); Writeln (Integer(y)); które spowodują pojawienie się na ekranie następujących napisów: 20 12 PP-6(58 z 82)
Instrukcje Instrukcje służą do opisu czynności wykonywanych na danych i dzielą się na: P instrukcje proste, tj. takie, które nie zawierają jako składowych innych instrukcji, P instrukcje strukturalne, zbudowane na podstawie pewnego schematu strukturalizacji kilku instrukcji, P instrukcję asemblerową umożliwiającą pisanie fragmentów tekstów źródłowych bezpośrednio w asemblerze Poszczególne instrukcje oddziela się średnikami. PP-6(59 z 82)
P instrukcję przypisania, P instrukcję skoku, Pinstrukcję pustą, Instrukcje Instrukjce proste Do instrukcji prostych zaliczamy: P instrukcję wywołania procedury i funkcji (będzie w temacie dotyczącym funkcji i procedur), P instrukcję dziedziczenia (będzie w temacie dotyczącym przetwarzania obiektów). PP-6(60 z 82)
Instrukcje Instrukcja przypisania Instrukcja przypisania służy do przypisania zmiennej nowej wartości. Ogólna jej postać jest następująca: odwołanie-do-zmiennej:=wyrażenie Instrukcja ta powoduje obliczenie wartości wyrażenia prawostronnego i przypisanie tej wartości odwołaniu do zmiennej występującemu z lewej strony symbolu przypisania := (dwukropek i znak równości). Wartość wyrażenia musi być przy tym zgodna w sensie przypisania PP-6(61 z 82) z typem zmiennej.
Instrukcje Instrukcja przypisania W części operacyjnej funkcji (będzie dalej) powinna wystąpić co najmniej jedna instrukcja przypisania postaci nazwa-funkcji:=wyrażenie lub Result:=wyrażenie gdzie Result oznacza predefiniowany identyfikator, lokalny w każdej funkcji. PP-6(62 z 82)
Instrukcje Przykłady Instrukcja przypisania a:=1; b[1]:=2*c-d/(e[3,4]+f); war_log:=true; tekst:= Delphi + + Pascal ; x:=x+1; warunek:=a=b; x[i*(i+1)+1,j]:=2; PP-6(63 z 82)
Instrukcje Instrukcja skoku Instrukcja skoku jest jedyną instrukcją języka Delphi Pascal, której stosowanie podobnie jak w standardowym Pascalu nie jest zalecane. Jej używanie zmniejsza bowiem przejrzystość programu, ogranicza optymalizację kodu wynikowego wykonywaną przez kompilator i utrudnia dowodzenie poprawności programu, modułu czy biblioteki. Instrukcja ta może być zawsze zastąpiona instrukcjami dopóki lub powtarzaj (będzie dalej). Instrukcja skoku wymaga podania etykiety, która jest identyfikatorem lub ciągiem do dziesięciu cyfr dziesiętnych (od 0 do 4294967295) poprzedzonym ewentualnie zerami (zera te nie są znaczące). Etykiety powinny być zadeklarowane (dotyczy to także przypadku, gdy etykieta jest ciągiem cyfr). PP-6(64 z 82)
Deklaracje etykiet mają postać Instrukcje Instrukcja skoku label lista-etykiet; przy czym w liście etykiet poszczególne etykiety oddziela się przecinkami. Każda instrukcja może być poprzedzona jedną lub kilkoma etykietami. Instrukcja poprzedzona jedną etykietą ma postać etykieta: instrukcja PP-6(65 z 82)
Instrukcje Instrukcja skoku Do instrukcji poprzedzonej etykietą można przekazać sterowanie za pomocą instrukcji skoku o następującej postaci: goto etykieta Instrukcja, do której ma nastąpić przejście może występować przed lub po odnośnej instrukcji skoku. Obowiązuje przy tym zasada, że instrukcja poprzedzona etykietą musi występować w tym samym bloku, co instrukcja skoku z tą etykietą (nie jest dozwolony skok do wnętrza i na zewnątrz procedury lub funkcji). Ponadto skok do wnętrza instrukcji strukturalnej, choć dozwolony (kompilator nie wykaże błędu), może mieć nieokreślone skutki. PP-6(66 z 82)
Instrukcje Instrukcja pusta Zapisanie instrukcji pustej nie wymaga użycia żadnego symbolu języka i nie powoduje ona wykonania żadnych czynności. Instrukcję pustą stosuje się w tych kontekstach, w których jest wymagane użycie instrukcji, ale chce się uniknąć wykonania jakiejkolwiek czynności, lub w celu ułatwienia opracowywania programu. PP-6(67 z 82)
Instrukcje Instrukcje strukturalne Do instrukcji strukturalnych zaliczamy: P instrukcję złożoną, P instrukcje warunkowe ( jeśli i wyboru), P instrukcje iteracyjne ( dla, dopóki i powtarzaj ), P instrukcję wiążącą, P instrukcje obsługi warunków i stanów wyjątkowych (raise, try...except i try...finally). PP-6(68 z 82)
Instrukcje Instrukcja złożona Instrukcja ta tworzy z ciągu instrukcji jedną i używana jest w przypadku, gdy składnia języka wymaga użycia jednej instrukcji, a niezbędne jest wykonanie wielu. Instrukcje wchodzące w skład instrukcji złożonej wykonywane są sekwencyjnie. PP-6(69 z 82)
Instrukcje Instrukcja złożona Struktura instrukcji złożonej jest następująca: begin instrukcja-1; instrukcja-2;... instrukcja-n end Przykład begin a:=1; b.c:=2; d[1,2]:=3 end PP-6(70 z 82)
Instrukcje Instrukcje warunkowe Instrukcje warunkowe uzależniają wykonanie innych instrukcji od spełnienia określonego warunku. W języku Delphi Pascal istnieją dwie instrukcje warunkowe: P instrukcja jeśli (mająca dwie postacie), P instrukcja wyboru. PP-6(71 z 82)
Instrukcje Instrukcja jeśli Instrukcja ta uzależnia wykonanie innej lub innych instrukcji od spełnienia lub niespełnienia podanego warunku. Ogólna postać instrukcji jeśli jest następująca: if wyrażenie then instrukcja lub if wyrażenie then instrukcja else instrukcja przy czym wartością wyrażenia powinna być wartość logiczna True lub False. PP-6(72 z 82)
Przykłady Instrukcje Instrukcja jeśli 1) if x<y then a:=0 else a:=1 Zapis równoważny: if x>=y then a:=1 else a:=0 2) if x=(y=z) then x:=y=x else y:=x=z PP-6(73 z 82)
Instrukcje Instrukcja jeśli Instrukcje warunkowe jeśli mogą być zagnieżdżone. Z zagnieżdżoną instrukcją jeśli mamy do czynienia wówczas, gdy po słowach then lub else występuje znowu instrukcja jeśli, która z kolei może zawierać następną instrukcję tego typu itd. W zagnieżdżonych instrukcjach jeśli obowiązuje zasada, że każda jednostka else jest przyporządkowana najbliższej poprzedzającej ją jednostce then, dla której nie wystąpiła jeszcze jednostka else. PP-6(74 z 82)
Instrukcje Instrukcja jeśli Przykłady if a<0 then if b<>0 then x:=a/b Instrukcję tę krócej można zapisać następująco: if (a<0) and (b<>0) then x:=a/b PP-6(75 z 82)
Instrukcje Instrukcja jeśli Przykłady Rozważmy następujący schemat: if y<0 then if z>0 then if x<>0 then a:=(y+2)/x else else else a:=1 Użycie dwóch jednostek else z instrukcją pustą jest konieczne! PP-6(76 z 82)
Instrukcje Przykłady Instrukcja jeśli Opuszczenie jednostek else, tj. instrukcja: if y<0 then if z>0 then if x<>0 then a:=(y+2)/x else else a:=1 else a:=1 odpowiadałoby schematowi z lewej strony. PP-6(77 z 82)
Instrukcje Instrukcja wyboru Instrukcja ta służy do wykonywania różnych operacji w zależności od wartości pewnej zmiennej. Jej ogólna postać jest następująca: case wyrażenie of sekwencja-instrukcji-wyboru end lub (verté) PP-6(78 z 82)
Instrukcje Instrukcja wyboru case wyrażenie of sekwencja-instrukcji-wyboru else instrukcja end gdzie wartość wyrażenia, zwanego selektorem, musi być typu porządkowego. Sekwencja instrukcji wyboru składa się z instrukcji, przy czym każda z nich poprzedzona jest jedną lub kilkoma stałymi wyboru, które od instrukcji oddzielone są dwukropkiem. Poszczególne stałe wyboru oddzielane są przecinkami i mogą mieć postać: stała lub stała.. stała PP-6(79 z 82)
Przykłady Instrukcje Instrukcja wyboru case miesiac of 1, 3, 5, 7, 8, 10, 12 : dni:=31; 2 : dni:=28; 4, 6, 9, 11 : dni:=30 end Jeśli zmienna miesiac będzie zadeklarowana następująco: var miesiac : 1.. 12; to powyższa instrukcja może być też zapisana w postaci: case miesiac of 2 : dni:=28; 4, 6, 9, 11 : dni:=30; else dni:=31 end PP-6(80 z 82)
Instrukcje Przykłady case a+b of 1.. 10 : begin x:=5; y:=(a+2)/10 end; 11.. 100 : x:=a*a; else begin x:=(a+2)/10; y:=5 end end; Instrukcja wyboru case znak of + : k:=1; : k:=2 end; PP-6(81 z 82)
... i to wszystko na dzisiaj Zapraszam na stronę www.cs.put.poznan.pl/amarciniak/ podstrona Dydaktyka PP-6(82 z 82)