Dátové typy - reťazcové
Všetky premenné majú typ. Free Pascal podporuje niektoré základné typy ako Turbo Pascal, s niektorými ďalšími typmi z Delphi. Programátor môže definovať aj svoje vlastné typy, ktoré sú v podstate definíciou identifikátora, ktorý môže byť použitý na určenie tohoto vlastného typu pri deklarácii premennej neskôr v zdrojovom kóde.
Obsah článku
Deklarácia typu
type
identifikator_typu = typ
FreePascal má sedem hlavných typov:
- jednoduché typy
- reťazcové typy
- štruktúrované typy
- typ ukazovateľ
- procedurálny typ
- všeobecný typ
- špecializovaný typ
- identifikátor typu
Reťazcovétypy
Char
Char má veľkosť presne 1 bajt a obsahuje práve jeden znak.
- Znaková konštanta môže byť zadaná uzatvorením znaku do apostrofovov, napríklad znakové konštanty sú a alebo A.
- Znak môže byť zadaný jeho znakovou hodnotou (zvyčajne ASCII kód), pridaním číselného symbolu (#) pred poradovú hodnotu, napríklad zadanie #65 značí to isté ako A.
- Pre zadanie ASCII hodnoty menšej ako 27 môže byť použitý znak striešky (^) spolu s písmenom, takže ^G zodpovedá #7 (G je siedme písmeno v angl. abecede.)
- Pre zadanie znaku apostrofu, je potrebné napísať ho dvakrát za sebou, takže predstavuje jeden znak apostrofu.
Reťazce
Free Pascal podporuje typ String
tak, ako je definovaný v Turbo
Pascale (postupnosť znakov so zadanou dĺžkou) aj ANSI reťazce ako sú
definované v Delphi.
Význam deklarácie reťazca je interpretovaný rôzne, v závislosti na
prepínači {$H}
. ANSI reťazec a krátky reťazec sú zameniteľné.
Prekladač vždy použije príslušnú konverziu tyou, ale dajte pozor na
to, že výsledok výrazu, ktorý obsahuje ANSI reťazec a krátky reťazec
bude vždy ANSi reťazec.
Krátke reťazce
Deklarácia reťazca deklaruje krátky reťazec ak:
- Ak je vypnutý prepínač
{$H-}
, bude deklarácia reťazca vždy deklaráciou krátkeho reťazca. - Ak je zapnutý prepínač
{$H+}
a je zadaná dĺžka, je deklaráciadeklaráciou krátkeho reťazca.
Preddefinovaný typ ShortString
je definovaný ako reťazec s dĺžkou 255:
ShortString = String[255];
Ak nie je zadaná dĺžka reťazca, je použitá predvolená dĺžka 255. Dĺžku
reťazca môžete získať pomocou štandardnej funkcie Length
:
{$H-}
Type
NameString = String[10];
StreetString = String;
NameString
môže obsahovať najviac 10 znakov. StreetString
môže
obsahovať až 255 znakov.
ANSI reťazce
ANSI reťazce sú reťazce, ktoré nemajú dĺžkový limit. Sú to počítané
odkazy zakončené nulou. Interne je ANSI reťazec spracovávaný ako
ukazovateľ, ale toto je spracovávané transparentne, čiže môžete s nimi
pracovať ako s obyčajným krátkym reťazcom. ANSI reťazce môžu byť
definované pomocou preddefinovaného typu AnsiString
.
Ak je zapnutý prepínač {$H}
, potom definícia reťazca pomocou bežného
kľúčového slova String bez zadania dĺžky, bude považovaná za ANSI
reťazec. Ak je zadaná dĺžka reťazca, bude použitý krátky reťazec, bez
ohľadu na nastavenie {$H}
.
Ak je reťazec prázdny (‚‘), potom má interný ukazovateľ hodnotu Nil
.
Ak reťazec nie je prázdny, potom ukazovateľ ukazuje na štruktúru v
pamäťovej halde. Interná reprezentácia kao ukazovateľa a automatické
zakončenie nulou umožňuje pretypovanie ANSI reťazca na PChar
. Ak je
reťazec prázdny (teda ukazovateľ je nil), prekladač zaistí aby
pretypovaný PChar
ukazoval na nulový bajt.
Priradenie ANSI reťazca do iného, nevyvoláva presun aktuálneho reťazca. Priradenie
S2:=S1;
spôsobí, že počet odkazov S2
bude znížený o jedna, počet odkazov S1
bude zvýšený o jedna a nakoniec je S1
(ako ukazovateľ) prekopírovaný
do S2
, čím je významne zvýšená rýchlosť kódu. Ak počet odkazov
dosiahne nulu, je automaticky uvoľnená pamäť obsadená reťazcom, takže
nenastávajú pamäťové úniky.
Pri deklarácii ANSI reťazca, prekladač Free Pascal alokuje pamäť len
pre ukazovateľ a tento ukazovateľ je nastavený na Nil
, čiže reťazec
je inicializovaný ako prázdny. Toto platí pre lokálne a globálne ANSi
reťazce alebo ANSI reťazce, ktoré sú súčasťou štruktúry (polia,
záznamy alebo objecty). Toto znamená dodatočnú réžiu, napríklad
deklarácia
var
A : Array[1..100000] of string;
bude kopírovať 100 000 krát Nil
do A
. Keď A
opustí rozsah, potom bude
počet odkazov 100 000 reťazcov znížený o 1, pre každý z týchto
reťazcov. Toto všetko je vykonané transparentne (skryto pred
programátorom), ale vzhľadom k výkonu, je to dôležité.
Pre získanie dĺžky ANSI reťazca musí byť použitá funkcia Length
. Pre
nastavenie dĺžky ANSI reťazca musí byť použitá funkcia SetLength
.
Konštanty typu ANSI reťazce majú počet odkazov -1 a sú spracovávané
samostatne.
Ak je to potrebné, sú ANSI reťazce konvertované prekladačom na krátke reťazce,čiže použitie ASNI reťazcov a krátkych reťazcov môže byť podľa potreby miešané bez problémov.
ANSI reťazce môžu byť pretypované na typy PChar
alebo Pointer
:
var P : Pointer;
PC : PChar;
S : AnsiString;
begin
S :=This is an ansistring;
PC:=Pchar(S);
P :=Pointer(S);
Medzi týmito dvoma pretypovaniami je rozdiel:
- keď je prázdny ANSI reťazec pretypovaný na ukazovateľ, bude mať
ukazovateľ hodnotu
Nil
. - keďje prázdny ASNI reťazec pretypovaný na
PChar
, bude mať ukazovateľ hodnotu ukazujúcu na nulový bajt (prázdny reťazec).
Výsledok takéhoto pretypovania musí byť používaný opatrne, vo
všeobecnosti je lepšie považovať výsledok takéhoto pretypovania za
read-only, teda vhodný na poslanie do procedúry, ktorá potrebuje ako
argument konštantu PChar
. Nie je vhodné používať pretypovanie v
prípade:
- výrazov,
- reťazcov, ktoré majú počet odkazov väčší ako 1 (volajte
uniquestring
na zaistenie, že reťazec má počet odkazov 1)
Dlhé reťazce
Dlhé reťazce (WideStrings
– používané pre reprezentáciu reťazcov so
znakmi unicode) sú implementované rovnako ako ANSI reťazce:
- počítané odkazy,
- nulou zakončené polia,
rozdiel je len v tom, že sú implementované ako polia typov WideChar
namiesto Char
. WideChar
je dvojbajtový znak (prvok DBCS - Double
Byte Character Set). Pre prácu s dlhými reťazcami platia rovnaké
pravidlá ako pre ANSI reťazce. Prekladač transparentne konvertuje dlhé
reťazce na ANSI reťazce a naopak.
Podobne ako pretypovanie ANSI reťazca na nulou ukončené pole znakov
PChar
, môže byť dlhý reťazec konvertovaný na nulou ukončené pole
znakov PWideChar
. Pamätajte, že pole PWideChar
je zakončené dvoma
nulovými bajtmi namiesto jedným, takže pretypovanie na PChar
nie je
automatické.
Prekladač samotný neposkytuje podporu pre konverziu Unicode do ASNI reťazcov a naopak. V jednotke System sú dve procedurálne premenné, ktoré môžu byť použité na obslúženie konverzie.
Reťazcové konštanty
Pre zadanie reťazcovej konštanty, musí byť reťazec uzatvorený do
apostrofov, rovnako ako typ Char
, ale tu je možné zadať viac ako
jeden znak. Keď S
je typu String
, platné priradenia môžu vyzerať
takto:
S := This is a string.;
S := One+, Two+, Three;
S := This isnt difficult !;
S := This is a weird character : #145 !;
Ako môžete vidieť, jeden znak apostrofu je reprezentovaný pomocou 2 apostrofov, hneď za sebou. Cudzie znaky môžu byť zadané pomocou ich hodnoty znaku (zvyčajne ASCII kód). Príklad ukazuje, že môžu byť pridané viaceré reťazce, výsledkom je ich prosté spojenie, bez medzier medzi nimi.
4i je reťazcová konštanta uchovávaná ako ANSI reťazce alebo ako krátky
reťazce závisí na nastavení prepínača {$H}
.
PChar
Free Pascal podporuje Delphi implementáciu typu PChar
. PChar
je
definovaný ako ukazovateľ na typ Char
, ale umožňuje dodatočné
operácie. Typ PChar
možno chápať ako najlepší ekvivalent Pascalu k
nulou zakončeným reťazcom v C, teda premenná typu PChar
je
ukazovateľ, ktorý ukazuje na pole typov Char
, ktoré je zakončené
nulovým znakom (#0
). Free Pascal podporuje inicializáciu typových
končtánt PChar
alebo priame priradenie. Napríklad nasledujúce časti
kódu sú ekvivalentné:
program one;
var P : PChar;
begin
P := This is a null-terminated string.;
WriteLn (P);
end.
má rovnaký výsledok ako
program two;
const P : PChar = This is a null-terminated string.
begin
WriteLn (P);
end.
Tieto príklady ukazujú, že je možné zapísať obsah reťazca do súboru
typu Text
. Jednotka Strings
obsahuje procedúry a funkcie pre
manipuláciu s typom PChar
ako v štandardnej knižnici C. Keďže PChar
je
ekvivalent k ukazovateľu na premennú typu Char
, je možné aj toto:
Program three;
Var S : String[30];
P : PChar;
begin
S := This is a null-terminated string.#0;
P := @S[1];
WriteLn (P);
end.
dostanete rovnaký výsledok ako v dvoch predchádzajúcich príkladoch.
Nulou zakončené reťazce nemôžu byť pridané ako bežné reťazce Pascalu.
Ak majú byť spojené dva reťazce typu PChar
, musia byť použité funkcie
z jednotky Strings
.
Ale je možná aritmetika ukazovateľov – možno použiť operátory +
a -
,
P
a Q
sú typu PChar
, I
je typu Longint
:
Operácia | Výsledok |
---|---|
P + I | pripočíta I k adrese ukazovanej P |
I + P | pripočíta I k adrese ukazovanej P |
P - I | Odpočíta I od adresy ukazovanej P |
P - Q | výsledkom (Integer) je rozdiel medzi 2 adresami (alebo počet znakov medzi P a Q ) |