Pchar

Ogólna informacja o typie danych

PChar jest typem danych, tzw. wskaźnikowym. To znaczy w samej zmiennej przechowywany jest tylko adres w pamięci wskazujący na tzw. null-terminated string - ciąg znaków (String) zakończony znakiem #0.

Zastosowanie

Zastosowanie do skracania stringów

Dodatkowo typ PChar można używać do prostszego skracania zmiennej typu string o określoną ilość znaków. Zauważmy, że jest to tylko adres w pamięci, a koniec tej zmiennej nie jest określony przez długość, a przez wystąpienie zarezerwowanego znaku #0. Dzięki temu wystarczy, że przesuniemy taki wskaźnik w prawo, a "obetniemy" pierwszą część naszego ciągu znaków. Jednocześnie nie musimy troszczyć się o odpowiednią zmianę długości, gdyż koniec dalej jest końcem.

Przykład dla skracania stringów

var
  S: String;
  C: Integer;
begin
  Write('Podaj ciąg znaków: ');
  ReadLn(S);
  Write('Podaj całkowitą liczbę znaków, którą chcesz usunąć z ciągu: ');
  ReadLn(I);
  S:=String( PChar(S) + I );
  WriteLn(S);
end;

Można zauważyć tutaj dwie rzeczy:

  1. Można by zastosować zamiast tego funkcję Copy albo Delete. Ta pierwsza jednak wymagałaby wykonania kolejnej funkcji Length (chyba, że znamy długość string'a), zaś ta druga działałaby równie skutecznie tylko w tym przypadku, gdy przypisujemy wynik naszego "ucinania" pod tą samą zmienną. Przy zastosowaniu PChar nie ma takiej konieczności. Dodatkowo zastosowanie funkcji Copy jest mniej czytelne szczególnie, gdy ilość znaków do ucięcia nie jest w prostej zmiennej, tylko wyraża się bardziej rozbudowanym wyrażeniem.
  2. Zastosowałem tutaj coś, co mogłoby wyglądać jak dodawanie zmiennej typu Integer (liczba całkowita) do ciągu znaków. Musimy jednak pamiętać, że zmienna PChar jako taka jest liczbą, wskazującą tylko na adres w pamięci. Dodając więc liczbę całkowitą do wskaźnika "przesuwamy" jego wskazanie o żądaną liczbę bajtów, a zatem znaków (gdyż w zmiennej string każdy znak zajmuje 1 bajt). Dzięki temu uzyskujemy ciąg znaków rozpoczynający się od (I+1)-go znaku.

Przestroga

Rozważmy taki przykład:

function foo:PChar;
var 
  s:string;
begin
  s := 'Ala ma kota';
  result := PChar(s);
end;

Po wywołaniu powyższej funkcji program za alokuje w pamięci miejsce dla zmiennej s, przypisze jej tekst 'Ala ma kota', po czym zrzutuje ją na PChara i przypisze do wyniku. Niebezpieczeństwo jest takie, że po opuszczeniu funkcji zmienna s jest dealokowana, a wynik dalej pokazuje na miejsce w pamięci gdzie ona była. Jeżeli koniecznością jest zwracanie zmiennej typu PChar można zastosować jedną z poniżej podanych metod:

function foo:PChar;
var 
  s:string;
begin
  s:='Ala ma kota';
  result:=NewStr(s);// NewStr nie powinno być używane. Jest ono używane tylko dla kompatybilności wstecz
end;
function foo:PChar;
var
  s:string;
begin
  s:='Ala ma kota';
  GetMem(result, Length(s));
end;

Należy jednak pamiętać o zwolnieniu tak zaalokowanej pamięci poprzez funkcje: DisposeStr, lub w drugim przypadku przez FreeMem.

O ile nie zaznaczono inaczej, treść tej strony objęta jest licencją Creative Commons Attribution-ShareAlike 3.0 License