#7 P r o g r a m... Rys Struktura zmiennej typu string

Podobne dokumenty
Wykład IV PASCAL - łańcuch znaków, - procedury i funkcje, - sortowanie bąbelkowe

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja, - liczby losowe

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

INSTRUKCJA PUSTA. Nie składa się z żadnych znaków i symboli, niczego nie robi. for i := 1 to 10 do {tu nic nie ma};

Pascal - wprowadzenie

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Podstawy programowania

Wykład II PASCAL - podstawy składni i zmienne, - instrukcje wyboru, - iteracja cz. 1

Programowanie w Turbo Pascal

Język programowania PASCAL

Tablice. TYPE identyfikator tablicy = ARRAY [Indeksl,..., Indeksn] OF Typ; Dany identyfikator_ tablicy można wykorzystać w deklaracji VAR:

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Delphi Laboratorium 3

Programowanie w języku Python. Grażyna Koba

Instrukcje podsumowanie. Proste: - przypisania - wejścia-wyjścia (read, readln, write, writeln) - pusta - po prostu ; (średnik) Strukturalne:

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Lekcja 6: Pascal. Procedura i funkcja

Wstęp do programowania. Różne różności

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

1 Podstawy c++ w pigułce.

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

P R OGRA M OW A N I E KOMPUTERÓW Ćwiczenia laboratoryjne

Podstawy Programowania C++

Wykład PASCAL - Pliki tekstowe

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

Informatyka 1. Przetwarzanie tekstów

Podstawy programowania 2. Temat: Wprowadzenie do wskaźników. Przygotował: mgr inż. Tomasz Michno

typ zakres sposob zapamietania shortint integer bajty (z bitem znaku) longint byte word

Wrocław, dn. 19 kwietnia 2006 roku. Anna Kaleta Piotr Chojnacki IV rok, informatyka chemiczna Liceum Ogólnokształcące nr 10 we Wrocławiu

Laboratorium 6: Ciągi znaków. mgr inż. Leszek Ciopiński dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

1. Wprowadzanie danych z klawiatury funkcja scanf

Podprogramy. Procedury

Warsztaty dla nauczycieli

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Wykład 6. Operacje na łańcuchach znakowych

lekcja 8a Gry komputerowe MasterMind

Obsługa klawiszy specjalnych

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

Instrukcja standardowa Writeln

Podstawy programowania skrót z wykładów:

Podstawy programowania

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Pliki. Operacje na plikach w Pascalu

Ćwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Wstęp do programowania

Podstawy programowania w języku Visual Basic dla Aplikacji (VBA)

Wykład 2 Składnia języka C# (cz. 1)

2.Sprawdzanie czy podana liczba naturalna jest pierwsza Liczba pierwsza to liczba podzielna tylko przez 1 i przez siebie.

Ćwiczenie 2 Wczytywanie i zapisywanie do plików tekstowych

Spis treści WSTĘP CZĘŚĆ I. PASCAL WPROWADZENIE DO PROGRAMOWANIA STRUKTURALNEGO. Rozdział 1. Wybór i instalacja kompilatora języka Pascal

WIADOMOŚCI WSTĘPNE WPROWADZENIE DO JĘZYKA TURBO PASCAL. Klawisze skrótów. {to jest właśnie komentarz, moŝna tu umieścić dowolny opis}

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Zmienne, stałe i operatory

Programowanie strukturalne i obiektowe : podręcznik do nauki zawodu technik informatyk / Adam Majczak. Gliwice, cop

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

Pętla for. Wynik działania programu:

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

wagi cyfry pozycje

przedmiot kilka razy, wystarczy kliknąć przycisk Wyczaruj ostatni,

Procedury i funkcje. Przykład programu z procedurą. Definicja. Cechy procedury

Proste typy zmiennych języka C++ *) Zapis 3.4 e-38 jest równoważny zapisowi 3,

Analiza leksykalna 1. Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

Lab 9 Podstawy Programowania

PASCAL WPROWADZENIE. 1. Uruchom kompilator. 2. Struktura programu w Pascalu. 3. Komentarze

Wykład III PASCAL - iteracja cz, 2, - liczby losowe, - tablice

Pliki. Ze względu na typ zawartych w nich danych rozróżnia się trzy podstawowe rodzaje plików:

Procedury i funkcje - powtórzenie i uzupełnienia. Przykład funkcji potęgowanie przy wykładniku naturalnym

1 Podstawy c++ w pigułce.

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Instrukcje cykliczne (pętle) WHILE...END WHILE

Laboratorium 10: Maszyna stanów

DANE TEKSTOWE W JĘZYKU C/C++ - TABLICE ZNAKOWE

Wstęp do programowania. Procedury i funkcje. Piotr Chrząstowski-Wachtel

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Część 4 życie programu

Języki i metodyka programowania. Wprowadzenie do języka C

Podstawy programowania w języku C++

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

Tablice deklaracja, reprezentacja wewnętrzna

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

2. Łańcuchy tekstowe w PHP

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Zapis algorytmów: schematy blokowe i pseudokod 1

ŁAŃCUCHY W JĘZYKU C/C++

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Programowanie i techniki algorytmiczne

OPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)

PASCAL Kompendium. Środowisko TURBO PASCAL Skróty klawiaturowe. Edycja kodu Pomoc spis treści. Skopiowanie zaznaczonego bloku do schowka

Podstawy Programowania

Laboratorium Wstawianie skryptu na stroną: 2. Komentarze: 3. Deklaracja zmiennych

2 Przygotował: mgr inż. Maciej Lasota

Transkrypt:

11. OPERACJE NA ŁAŃCUCHACH ZNAKOWYCH 11.1. Opis typu i deklarowanie zmiennych łańcuchowych Typ łańcuchowy o nazwie string opisuje strukturę danych, złożoną z 255 elementów typu Char. Jest ona przeznaczona do pamiętania łańcuchów znakowych, czyli napisów (fragmentów tekstu). W jednej zmiennej typu string można przechować najwyżej 255 znaków, ale nie wszystkie stojące do dyspozycji miejsca muszą być wykorzystane. Dlatego odróżniamy długość deklarowaną zmiennej łańcuchowej od jej długości rzeczywistej. Długość deklarowana jest to maksymalna liczba znaków, jakie może pomieścić zmienna. Natomiast długość rzeczywista jest liczbą znaków, jaką zajmuje łańcuch, który jest aktualnie przechowywany w zmiennej..format zmiennej łańcuchowej w pamięci przedstawia przykład na rysunku 11.1. Pozycje zmiennej są numerowane kolejno od 0 do 255. W zmiennej L jest aktualnie pamiętany łańcuch Program. W takim razie rzeczywista długość łańcucha wynosi 7. Szczególną rolę odgrywa początkowa, zerowa pozycja zmiennej łańcuchowej. Przechowuje ona zawsze znak o numerze równym aktualnej długości łańcucha. Wobec tego w podanym przykładzie będzie tam się znajdować znak #7. Pisząc program, na ogół nie musimy pamiętać o zawartości zerowej pozycji łańcucha. Wynika to z faktu, że operatory i podprogramy łańcuchowe Turbo Pascala po wykonaniu operacji na łańcuchach same wpisują odpowiedni znak na zerową pozycję zmiennych łańcuchowych. L L[0] L[1] L[2] L[3] L[4][ L[5] L[6] L[7] L[8] L[9]... L[255] #7 P r o g r a m... Rys.11.1. Struktura zmiennej typu string Deklaracja zmiennej łańcuchowej wygląda, jak następuje: var Napis: string; Podobnie, jak to miało miejsce dla innych typów, również zmiennym typu string można nadać wartość początkową Wtedy zmienną deklarujemy po słowie const, na przykład: const L:string = Program ; 11.2. Własne typy łańcuchowe Bardzo często w programie używa się zmiennych łańcuchowych, o których wiemy, że ich długość rzeczywista jest na pewno mniejsza, niż 255 bajtów, Wtedy dla oszczędności pamięci można zdefiniować własny typ łańcuchowy o odpowiednio mniejszej długości deklarowanej. Na przykład, jeżeli wiadomo, że używane w programie napisy nie są dłuższe, niż jeden wiersz tekstu na ekranie, zajmujący 80 znaków, to zdefiniujemy typ: type S_80 = string[80]; W tej definicji S_80 jest dowolnie przyjętą nazwą, a w nawiasie kwadratowym po słowie string jest wpisana wartość 80, będąca deklarowaną długością zmiennych danego typu. Zauważmy, że każda zmienna typu S_80 będzie zajmować 81 bajtów pamięci jeden dodatkowy bajt na początku obszaru zmiennej zawiera informację o aktualnej długości pamiętanego łańcucha. 77

11.3. Stałe łańcuchowe Aby zapisać jawną stałą łańcuchową, odpowiedni ciąg znaków umieszcza się pomiędzy dwoma apostrofami; na przykład jawnymi stałymi łańcuchowymi są: Turbo Pascal Adam Mickiewicz 127 B:\JEZYKI\TP\TURBO.EXE Apostrofy zamykające łańcuch są bardzo ważne, bo dzięki nim kompilator odróżnia stałą łańcuchową od nazwy zmiennej lub od stałej liczbowej. Jeżeli w zapisie stałej łańcuchowej są tylko dwa apostrofy, jak w ostatnim przykładzie, to zapis taki reprezentuje łańcuch pusty. Jego aktualna długość wynosi 0. W bajcie zerowym takiego łańcucha znajduje się znak #0. (Nie jest to znak 0!) W przypadku, gdy w programie wielokrotnie występuje ten sam napis o znacznej długości, wygodnie jest stosować stałą łańcuchową definiowaną, jak w przykładzie poniżej: const C1= Nacisnij klawisz <Enter> ; C2= Wprowadz liczbe: ; W wyniku tej definicji, w dowolnym miejscu bloku, w którym definicja obowiązuje, nazwa C1 będzie rozumiana jako stała wartość łańcuchowa Nacisnij klawisz <Enter>, a nazwa C2 jako stała wartość łańcuchowa Wprowadz liczbe:. 11.4. Wykorzystanie instrukcji przypisania Podobnie, jak dla zmiennych innych typów, po lewej stronie operatora przypisania występuje nazwa zmiennej, w tym przypadku typu łańcuchowego (standardowego lub własnego), a po prawej wyrażenie, w tym przypadku wyrażenie o wartości łańcuchowej. Łańcuchy krótsze od deklarowanej długości zmiennej, lub tej samej jak ona długości, są kopiowane bez zmian. Natomiast, gdy chcemy przypisać łańcuch dłuższy, niż na to pozwala deklarowana długość zmiennej, to końcowe znaki łańcucha zostają po prostu obcięte. Ilustruje to poniższy przykład: Przykład 11.1. Instrukcje przypisania operujące na zmiennych łańcuchowych type S20=string[20] S12=string[12]; var Nazwisko: S20; Miasto:S12; Nazwisko:= Kowalski ; {Nazwisko = Kowalski } Miasto:= Konstantynopol ; {Miasto = Konstantynop } end. Łańcuchowi wolno przypisać znak. Na przykład, jeżeli: var Z:Char; L:string; to prawidłowe jest przypisanie: L:=Z; 78

W wyniku tej operacji L będzie łańcuchem o aktualnej długości równej 1. Natomiast przypisanie odwrotne jest niemożliwe, bo zmienna typu Char ma do dyspozycji jeden bajt pamięci, podczas gdy zmienna typu string wymaga 256 bajtów pamięci! 11.5. Odwoływanie się do elementów łańcucha Do elementów (czyli poszczególnych znaków) łańcucha można odwoływać się tak samo, jak do elementów jednowymiarowej tablicy. Takie odwołania mogą być przeznaczone zarówno do zapisu, jak odczytu znaków. Traktując łańcuch jako tablicę, warto stosować na początku programu dyrektywę kompilatora {$R+}. Zabezpiecza to przed błędami w przypadku przekroczenia deklarowanej długości łańcucha. Chcąc odczytać K ty znak łańcucha Lancuch i zapamiętać ten znak w zmiennej znakowej C, napiszemy zatem: C:=Lancuch[K]; przy czym K nie może być większe, niż aktualna długość łańcucha. W przykładzie 11.2 pokazano procedurę, która wyprowadza na ekran podany na jej wejście łańcuch W drukiem rozstrzelonym, wypisując spację (czyli znak #32) po każdym wyprowadzonym znaku. Zwróćmy uwagę na zastosowanie standardowej funkcji Length. Funkcja ta zwraca aktualną długość łańcucha, zapobiegając wypisaniu przypadkowych znaków, pamiętanych w obszarze poza aktualna długością zmiennej W. Przykład 11.2. Procedura wyprowadzająca łańcuch drukiem rozstrzelonym procedure Pisz_szeroko(W:string); for K:=1 to Length(W) do Write W[K]; Write(#32); Następny przykład pokazuje funkcję, która zwraca łańcuch, stanowiący ciąg N jednakowych znaków Z. Argument N nie może być większy, niż 255, więc jest typu Byte. Zwróćmy uwagę, że przy tej metodzie tworzenia łańcucha zerowy bajt nie wypełnia się samoczynnie należy wpisać do niego znak o numerze N. Wykorzystano w tym celu standardowa funkcję Chr, która zwraca znak o numerze zgodnym z jej argumentem. Przykład 11.3. Funkcja zwracająca łańcuch N jednakowych znaków Z function Lanc_znak(N:Byte;Z:Char):string; var Lanc:string; K:Byte; for K:=1 to N do Lanc[I]:=Z; Lanc[0]:=Chr(N); Lanc_znak:=Lanc; 79

11.6. Operacja sklejania łańcuchów Chcąc skleić dwa lub więcej łańcuchów, czyli połączyć je w jeden wspólny łańcuch, stosujemy operator sklejania (konkatenacji), który wygląda tak samo, jak operator dodawania. Otrzymane w ten sposób wyrażenie łańcuchowe przypisujemy do zmiennej łańcuchowej. Oczywiście wynik takiej operacji zależy od porządku składników. W poniższym przykładzie widać, że argumentami operacji sklejania mogą być również znaki: Przykład 11.4. Sklejanie łańcuchów i znaków const C1= Jan ; C2= Kowalski ; var S1,S2: string; S1:=C1+#32+C2; {S1= Jan Kowalski } S2:=C2+#32+C1; {S2= Kowalski Jan } 11.7. Porównywanie łańcuchów Porównywanie łańcuchów odbywa się za pomocą operatorów relacyjnych, działających na łańcuchach: =,<>,<,>,<=,>= Przy porównywaniu są sprawdzane numery porządkowe kodu ASCII kolejnych znaków dwóch porównywanych łańcuchów. Łańcuch mniejszy, to ten, który na wcześniejszej pozycji ma znak o mniejszym numerze porządkowym. Wynika stąd na przykład, że łańcuch pisany wielkimi literami jest mniejszy od tego samego łańcucha pisanego małymi literami. Łańcuchy są równe, gdy mają tę sama liczbę znaków i jednocześnie znaki na każdej ich pozycji są wzajemnie jednakowe. W przeciwnym przypadku łańcuchy są różne. W przykładzie 11.5 pokazano wykorzystanie operatora większości w procedurze, która sortuje zawartość tablicy łańcuchów w porządku alfabetycznym. Do sortowania zastosowano wcześniej już opisany w tej książce algorytm bąbelkowy. W programie pokazano także sposób zainicjowania tablicy łańcuchów przy jej deklarowaniu. Program Ex11_5; uses Crt; Przykład 11.5. Sortowanie tablicy łańcuchów w porządku alfabetycznym type Tab=array [1..6] of string; const T:Tab=('Tomasz','Jacek','Adam','Robert','Ewa','Beata'); procedure PokTab(var T:Tab); var I:Integer; for I:=Low(T) to High(T) do Writeln(T[I]); Writeln; 80

Przykład 11.5. c.d. procedure BubbleSort(var T:Tab); var K,J:Integer; Kopia:string; for K:=Low(T) to High(T)-1 do for J:=K+1 to High(T) do if T[K]>T[J] then Kopia:=T[K]; T[K]:=T[J]; T[J]:=Kopia; Clrscr; Poktab(T); Bubblesort(T); Poktab(T); Readln; end. 11.8. Funkcje i procedury standardowe operujące na łańcuchach Poniżej pokazano nagłówki definicji i krótki opis działania standardowych funkcji i procedur Turbo Pascala, przeznaczonych do operacji na łańcuchach. Ich stosowanie pozwala uniknąć konieczności odwoływania się do elementów łańcucha. Wszystkie automatycznie wpisują odpowiednią wartość do początkowego bajtu łańcuchów wynikowych, który przechowuje informację o aktualnej długości łańcucha. Przytoczone poniżej nagłówki służą jedynie do przekazania informacji o liczbie i typach argumentów poszczególnych funkcji i procedur. Oczywiście w naszych programach stosujemy jedynie wywołania odpowiednich funkcji i procedur, których gotowe definicje są wewnętrznie zakodowane w Turbo Pascalu. function Length(S:string):Integer; Zwraca aktualną długość łańcucha S. function Concat(S1,S2,... Sn):string; Zwraca łańcuch będący sklejeniem kolejnych argumentów S1, S2, Sn. Zamiast tej funkcji można zastosować operatory sklejania +. function Copy(S:string; Poz:Integer; D:Integer):string; Łańcuch wynikowy jest wycinkiem łańcucha S zaczynającym się od pozycji Poz, mającym długość określoną przez argument D. function Pos(S1,S2:string):Byte; Bada, czy w łańcuchu S2 znajduje się podłańcuch S1. Jeżeli nie ma takiego podłańcucha, zwraca wartość 0; w przeciwnym przypadku zwraca numer pozycji S2, od której rozpoczyna się pierwsze wystąpienie podłańcucha S1. procedure Delete(var S:string; Poz:Integer; D:Integer); 81

Wycina podłańcuch z łańcucha S. Wycięty podłańcuch zaczyna się od pozycji Poz i ma D znaków. Jeżeli Poz jest większa od aktualnej długości S, to postać łańcucha S nie ulega zmianie. procedure Insert(S1:string; var S2:string; N:Integer); Wstawia do łańcucha S2 podłańcuch S1, począwszy od pozycji następnej za znakiem N tym łańcucha S2. Jeżeli N jest większe od aktualnej długości S2, to podłańcuch S1 zostaje doklejony na końcu S2. procedure Str(X; var S:string); Przekształca daną X dowolnego typu liczbowego na łańcuch znaków, reprezentujący odpowiedni zapis dziesiętny tej danej. Pisząc argument X, można stosować parametry określające liczbę pozycji zapisu i liczbę miejsc po kropce dziesiętnej, podobnie jak w instrukcjach Write, Writeln. procedure Val(S:string; var X; var Kod:Integer); Przekształca łańcuch znakowy S, stanowiący poprawny zapis dowolnej liczby, na liczbę X, będącą zmienną odpowiedniego typu liczbowego. Jeżeli Łańcuch S był poprawnym zapisem liczby, to argument wyjściowy Kod przyjmuje wartość 0; w przeciwnym przypadku Kod jest numerem pozycji łańcucha S, na której wykryto pierwszy błąd zapisu. Uwaga: Procedura Val wykrywa także błąd zakresu dla X typu Real lub Longint. Dla innych typów do kontroli zakresu należy w programie zastosować dyrektywę kompilatora {$R+}. 11.9. Przykłady wykorzystania standardowych funkcji i procedur łańcuchowych Wprowadzając wartość liczbową z klawiatury, można łatwo popełnić błąd, polegający na próbie wprowadzenia niewłaściwego formatu liczby. Najprostszym przykładem może być użycie przecinka zamiast kropki dziesiętnej przy odczycie z klawiatury liczby rzeczywistej. Instrukcja Readln wykrywa to jako błąd wykonania, powodując natychmiastowe przerwanie programu, czemu towarzyszy wydrukowanie komunikatu: Error 106: Invalid numeric format. Taka sytuacja jest bardzo niewygodna, ponieważ konieczne jest ponowne uruchomienie programu od początku. Zatem lepiej jest napisać program w taki sposób, by użytkownik mógł po prostu, nie przerywając obliczeń, powtórnie wprowadzić poprawnie napisaną wartość liczby. Jedna z metod takiej programowej kontroli błędów wejścia polega na interpretacji wprowadzonego ciągu znaków jako łańcucha i próbie przekształcenia tego łańcucha na liczbę za pomocą procedury Val. Przykład 11.6 pokazuje odpowiednią procedurę własną, która realizuje tę metodę. Przykład 11.6. Zastosowanie procedury Val do programowej kontroli formatu liczby procedure CzytKontrol(var X:Real); var S:string[80]; Kod:Integer; repeat Write('Podaj liczbe: '); Readln(S); Val(S,X,Kod); if Kod<>0 then Writeln('Blad na pozycji ',Kod); until Kod=0; W procedurze zastosowano instrukcję powtarzająca repeat until, która tak długo powtarza prośbę o wprowadzenie liczby rzeczywistej X, dopóki format tej liczby nie będzie poprawny. Liczba jest odczytywana jako łańcuch znaków i jej zapis znakowy zostaje zapamiętany w zmiennej 82

S. Następnie procedura Val sprawdza format S. Jeżeli stanowi on bezbłędny zapis liczby, to będzie ona zapisana jako wartość typu Real w zmiennej X. Zmienna kontrolna Kod przyjmie wtedy wartość 0, co jest warunkiem zakończenia instrukcji repeat until. Jeżeli odczytany z klawiatury łańcuch S nie jest poprawnym zapisem liczby, to zostaje wyprowadzony komunikat o błędzie na określonej pozycji, a instrukcja powtarzająca rozpoczyna kolejny cykl pracy, ponownie prosząc użytkownika o wprowadzenie danej. Przykład 11.7 demonstruje program, w którym zdefiniowano funkcję, znajdująca liczbę wystąpień podłańcucha P w łańcuchu L. Łańcuch i podłańcuch są argumentami funkcji. W ciele funkcji zastosowano trzy spośród standardowych podprogramów Turbo Pascala: Length, Pos oraz Delete. Użyta w ciele funkcji instrukcja while do powtarza sekwencję trzech operacji: (1) Za pomocą funkcji Pos szukamy początkowej pozycji pierwszego wystąpienia podłańcucha. (2) Po jej znalezieniu zwiększamy o 1 wartość licznika wystąpień; funkcję tego licznika pełni tutaj zmienna Licznik. (3) Z badanego łańcucha za pomocą procedury Delete usuwamy znaleziony podłańcuch. Ta sekwencja trzech operacji powtarzana jest tak długo, dopóki instrukcja Pos(P,L) nie zwróci wartości 0. Przyjęcie przez Pos wartości 0 oznacza, ze w badanym łańcuchu L nie ma już więcej wystąpień podłańcucha P, więc w zmiennej Licznik znajduje się końcowy wynik, który należy przekazać na wyjście funkcji za pośrednictwem końcowej instrukcji przypisania. Przykład 11.7. Znajdowanie liczby wystąpień podłańcucha w łańcuchu program Ex11_7; {Zastosowanie standardowych funkcji i procedur łańcuchowych} uses Crt; type S_80 = string[80]; const L:S_80 = 'Adam Kowalski i Janina Kowal-Kowalska'; var P:S_80; W:Byte; function IlePodlanc(P,L:string):Byte; {Zwraca liczbę wystąpień podłańcucha P w łańcuchu L.} var Licznik:Byte; Pozycja,D:Integer; D:=Length(P); {Długość podłańcucha} Licznik:=0; while Pos(P,L)<>0 do Pozycja:=Pos(P,L); {Pozycja pierwszego wystąpienia P} Licznik:=Licznik+1; {Przyrost licznika wystąpień P w L} Delete(L,Pozycja,D) {Usunięcie z L kolejnego podłańcucha P} IlePodlanc:=Licznik; Clrscr; Writeln(L); Write('Wpisz szukany podlancuch: '); Readln(P); W:=IlePodlanc(P,L); Write('Liczba wystapien: ', W); Readln; end. W przypadku, gdy łańcuch L jest zainicjowany jako Adam Kowalski i Janina Kowal Kowalska, a chcemy znaleźć liczbę wystąpień podłańcucha Kowal, instrukcja while wykona trzy 83

kroki. Po każdym z nich łańcuch L jest krótszy w wyniku usunięcia kolejnego wystąpienia podłańcucha, jak pokazano poniżej: Adam Kowalski i Janina Kowal Kowalska {postać początkowa} Adam ski i Janina Kowal-Kowalska (po kroku nr 1} Adam ski i Janina Kowalska {po kroku nr 2} Adam ski i Janina ska {po kroku nr 3} Oczywiście, zmienna L użyta w programie głównym w instrukcji: W:=IlePodlanc(P,L); nie ulegnie zmianie w wyniku tego wywołania. Wiemy przecież z rozdziału o procedurach i funkcjach, że podprogramy kopiują użyte w wywołaniu wartości argumentów wejściowych do zmiennych lokalnych w obszarze stosu i dopiero na tych lokalnych zmiennych odbywają się odpowiednie działania. Dlatego zawartość zmiennej L programu głównego pozostaje nienaruszona. Przykład 11.8. Użycie funkcji Length do centrowania tekstu w elementach tablicy łańcuchów program Ex11_8; uses Crt; type S_80 = string[80]; Tab = array [1..6] of S_80; const T:Tab=('Ordinal types are a subset of simple types.', 'All simple types other than real types', 'are ordinal types.', 'Except for integer-type values,', 'the first value of every ordinal type', 'has ordinality 0.'); procedure Poktab(var T:Tab); var K:Integer; for K:=Low(T) to High(T) do Writeln(T[K]); Writeln; procedure Centruj(var T:Tab); var K:Integer; S:string; for K:=Low(T) to High(T) do S:=''; repeat S:=S+#32; until 2*Length(S)+Length(T[K])>=79; T[K]:=S+T[K]; Clrscr; Centruj(T); PokTab(T); Readln; end. W przykładzie 11.8 pokazano program, w którym zainicjowano tablicę łańcuchów fragmentami tekstu w języku angielskim. Program zawiera dwie procedury własne. Procedura Poktab wyprowadza w kolejnych wierszach zawartość tablicy. Procedura Centruj modyfikuje 84

zawartość tablicy, doklejając na początek każdego jej elementu T[K] łańcuch S, złożony z pewnej liczby spacji. Łańcuch ten, początkowo pusty, jest konstruowany przez kolejne doklejanie pojedynczych spacji w zagnieżdżonej pętli repeat until Dla każdego elementu T[K] doklejanie spacji kończy się, gdy suma podwójnej długości łańcucha S oraz długości łańcucha T[K] osiągnie wartość, odpowiadającą liczbie znaków, mieszczących się w jednym wierszu ekranu, a więc po spełnieniu relacji: 2*Length(S)+Length(T[K]}>=79 W rezultacie tego postępowania, fragmenty tekstu, zawarte w kolejnych elementach tablicy, zostaną wypisane symetrycznie względem środka ekranu, jak pokazano poniżej. Ordinal types are a subset of simple types. All simple types other than real types are ordinal types. Except for integer-type values, the first value of every ordinal type has ordinality 0. 85