Реалізація рядків типу PChar в пам’яті комп’ютера. Типи PAnsiChar, PWideChar. Виділення пам’яті для рядків. Доступ за індексом
Зміст
- 1. Представлення ASCIIZ-рядків у мові Паскаль. Типи PChar, PAnsiChar, PWideChar
- 2. Функції для роботи з типами PChar, PAnsiChar, PWideChar. Перелік
- 3. Виділення пам’яті для рядків типу PAnsiChar, PWideChar. Функції AnsiStrAlloc, WideStrAlloc
- 4. Доступ до окремого символу рядка типу PChar, PAnsiChar, PWideChar. Операція доступу за індексом []
- 5. Функція StrNew та процедура StrDispose. Виділення та звільнення пам’яті для рядків PAnsiChar та PWideChar
- 6. Функції StrPas та StrPCopy. Перетворення з типу String в тип PChar і навпаки
- Споріднені теми
Пошук на інших ресурсах:
1. Представлення ASCIIZ-рядків у мові Паскаль. Типи PChar, PAnsiChar, PWideChar
Крім стандартного представлення з допомогою типу String, у мові Паскаль рядки можуть бути представлені типами PChar, PAnsiChar та PWideChar. Ці типи визначають так звані ASCIIZ-рядки. Кожен ASCIIZ-рядок завершується спеціальним нульовим символом (нуль-термінатором), який позначається як ‘\0’ в C-орієнтованих мовах або #0 в Паскалі.
На рисунку 1 відображається представлення ASCIIZ-рядка у пам’яті комп’ютера.
Рисунок 1. Представлення ASCIIZ-рядка в пам’яті комп’ютера
Тип PChar описує покажчик на тип Char
type
PChar = ^Char;
Модифікацією типу PChar є типи PAnsiChar та PWideChar, які є покажчиками відповідно на типи AnsiChar та WideChar. Більш детально про символьні типи у Free Pascal та Delphi описується тут.
⇑
2. Функції для роботи з типами PChar, PAnsiChar, PWideChar. Перелік
Для роботи з рядками типу PChar використовуються наступні функції:
- StrCat, StrLCat – реалізує конкатенацію рядків;
- StrComp, StrIComp, StrLComp, StrLIComp – порівнюють два рядки;
- StrCopy, StrECopy, StrLCopy – копіюють значення одного рядка в інший;
- StrDispose – знищує рядок та пам’ять, раніше виділену для нього;
- StrEnd – повертає покажчик на символ, що завершує рядок;
- StrLen – повертає довжину рядка;
- StrLower – перетворює рядок в нижній регістр;
- StrMove – переміщує один рядок на місце іншого рядка;
- StrNew – виділяє пам’ять для нового рядка;
- StrPas – конвертує рядок типу PChar в рядок типу String;
- StrPCopy – копіює рядок типу String в рядок типу PChar;
- StrPos – знаходить підрядок в рядку;
- StrRScan, StrScan – знаходить позицію вказаного символа в рядку;
- StrUpper – перетворює рядок в верхній регістр та повертає покажчик на нього.
⇑
3. Виділення пам’яті для рядків типу PAnsiChar, PWideChar. Функції AnsiStrAlloc, WideStrAlloc
Для того, щоб використовувати рядки типу PAnsiChar, PWideChar для них попередньо потрібно виділити необхідний фрагмент пам’яті. Для виділення пам’яті використовуються наступні функції
function AnsiStrAlloc(Size: Cardinal): PAnsiChar; function WideStrAlloc(Size: Cardinal): PWideChar;
тут
- Size – розмір рядка в символах. Для рядків типу PAnsiChar кожен символ займає 1 байт. Для рядків типу PWideChar кожен символ займає 2 байти (кодування Unicode).
Приклад.
program Project1; {$APPTYPE CONSOLE} uses SysUtils; var ps1 : PAnsiChar; ps2 : PWideChar; s : string; begin // Функції AnsiStrAlloc, WideStrAlloc. // Демонструється ввід рядка з клавіатури консолі // та копіювання цього рядка в типи AnsiStrAlloc, WideStrAlloc // 1. Ввести рядок типу String з клавіатури Write('s = '); Readln(s); // 2. Функція AnsiStrAlloc // 2.1. Виділити пам'ять для рядка PAnsiChar, // розмір пам'яті рівний розміру рядка s ps1 := AnsiStrAlloc(Length(s)); // 2.2. Скопіювати рядок s => ps1 StrPCopy(ps1, s); // 2.3. Вивести ps1 Writeln('ps1 = ', ps1); // 3. Функція WideStrAlloc // 3.1. Виділити пам'ять для рядка PWideChar ps2 := WideStrAlloc(Length(s)); // 3.2. Копіювання s => ps2 StrPCopy(ps2, s); // 3.3. Вивести ps2 Writeln('ps2 = ', ps2); Readln; end.
Результат
s = abcdef ps1 = abcdef ps2 = abcdef
⇑
4. Доступ до окремого символу рядка типу PChar, PAnsiChar, PWideChar. Операція доступу за індексом []
Для рядків типу PChar, PAnsiChar та PWideChar є можливість доступитись до заданого символу з допомогою операції індексування []. У загальному випадку доступ до елементу рядка виглядає так:
S[index]
тут
- S – рядок типу PChar, PAnsiChar, PWideChar;
- index – позиція символа, яка починається з 0.
Окремі символи рядків типу PChar, PAnsiChar, PWideChar можуть змінюватись. Це означає, що операція доступу за індексом [] може використовуватись як у виразі, так і в лівій частині оператора присвоювання.
Приклад.
У прикладі з допомогою доступу за індексом реалізується створення рядка типу PAnsiChar та PWideChar.
program Project1; {$APPTYPE CONSOLE} uses SysUtils; var ps1 : PAnsiChar; ps2 : PWideChar; i : Integer; s : string; begin // Доступ за індексом [] // 1. Створити рядок AnsiChar // 1.1. Виділити пам'ять для рядка ps1 := AnsiStrAlloc(10); // 1.2. Записати слово 'Hello!' в рядок ps1 ps1[0] := 'H'; ps1[1] := 'e'; ps1[2] := 'l'; ps1[3] := 'l'; ps1[4] := 'o'; ps1[5] := '!'; ps1[6] := #0; // символ кінця рядка // 1.3. Вивести рядок в циклі Write('ps1 = '); for i := 0 to StrLen(ps1) do Write(ps1[i]); Writeln; // 2. Створити рядок WideChar // 2.1. Виділити пам'ять для рядка ps2 := WideStrAlloc(15); // 2.2. Записати слово 'BestProg' в рядок ps2 ps2[0] := 'B'; ps2[1] := 'e'; ps2[2] := 's'; ps2[3] := 't'; ps2[4] := 'P'; ps2[5] := 'r'; ps2[6] := 'o'; ps2[7] := 'g'; ps2[8] := #0; // кінець рядка // 2.3. Вивести рядок Writeln('ps2 = ', StrPas(ps2)); // 2.4. Додати до рядка '.net' ps2[8] := '.'; ps2[9] := 'n'; ps2[10] := 'e'; ps2[11] := 't'; ps2[12] := #0; // 2.5. Змінити 'B'->'b', 'P'->'p' ps2[0] := 'b'; ps2[4] := 'p'; // 2.6. Вивести ps2 на екран Writeln('ps2 = ', StrPas(ps2)); Readln; end.
Результат
ps1 = Hello! ps2 = BestProg ps2 = bestprog.net
⇑
5. Функція StrNew та процедура StrDispose. Виділення та звільнення пам’яті для рядків PAnsiChar та PWideChar
Для роботи з рядками типу PChar, PAnsiChar та PWideChar обов’язковими операціями є виділення та звільнення пам’яті в динамічній області. Для виконання цих операцій використовуються функції StrNew та StrDispose.
Функція StrNew створює новий рядок на основі існуючого та має наступні оголошення для типів PAnsiChar та PWideChar
function StrNew(const Str: PAnsiChar): PAnsiChar; function StrNew(const Str: PWideChar): PWideChar;
тут
- Str – константний рядок, для якого виділяється пам’ять.
Після закінчення роботи з рядком (в кінці програми, процедури чи деякої функції) потрібно звільнити пам’ять, виділену для цього рядка. Для цього призначена процедура StrDispose
procedure StrDispose(Str: PAnsiChar); procedure StrDispose(Str: PWideChar);
тут
- Str – рядок, для якого потрібно звільнити пам’ять.
Приклад.
У прикладі демонструється виділення пам’яті для рядка, який вводиться з клавіатури для консольного додатку. У цьому випадку довжина рядка на початку програми не відома і визначається у ході виконання програми.
program Project1; {$APPTYPE CONSOLE} uses SysUtils; var ps1 : PWideChar; s : string; begin // Функція StrNew, процедура StrDispose. // Демонструється виділення пам'яті для рядка, // що введений з клавіатури. Довжина рядка на початку програми невідома. // 1. Створити вихідний рядок, // рядок вводиться з клавіатури в консольному додатку Write('s = '); Readln(s); // 2. Конвертувати s => ps1 // 2.1. Виділити пам'ять для рядка ps1 функцією StrNew, // розмір пам'яті рівний довжині рядка s ps1 := StrNew(WideStrAlloc(Length(s))); // 2.2. Скопіювати рядок s => ps1 StrPCopy(ps1, s); // 3. Вивести рядок ps1 Writeln('ps1 = ', StrPas(ps1)); // 4. Звільнити пам'ять, виділену для рядка ps1 StrDispose(ps1); Readln; end.
Результат.
s = BestProg ps1 = BestProg
⇑
6. Функції StrPas та StrPCopy. Перетворення з типу String в тип PChar і навпаки
Корисними при використанні рядків у програмах є функції взаємного перетворення між форматами представлення рядкыв типу String та типу PChar. Для загального типу String використовуються його реалізації типів AnsiString та UnicodeString в яких символ займає відповідно 1 та 2 байти. Для узагальненого типу PChar так само існує різновиди, це типи PAnsiChar та PWideChar які враховують різні системи кодування в яких символи займають відповідно 1 та 2 байти.
Щоб перетворити з типів PAnsiChar та PWideChar у тип String потрібно використати функцію StrPas, яка має наступні оголошення
function StrPas(const Str: PAnsiChar): AnsiString; function StrPas(const Str: PWideChar): UnicodeString;
тут
- Str – рядок, який потрібно перетворити відповідно в тип AnsiString або UnicodeString.
Для перетворення з типу String в типи PAnsiChar та PWideChar використовується функція StrPCopy. Функція має наступні реалізації
function StrPCopy(Dest: PAnsiChar; const Source: AnsiString): PAnsiChar; function StrPCopy(Dest: PWideChar; const Source: UnicodeString): PWideChar;
Приклад.
program Project1; {$APPTYPE CONSOLE} uses SysUtils; var ps1 : PAnsiChar; ps2 : PWideChar; s : string; begin // Функції StrPas та StrPCopy // 1. Функція StrPas // 1.1. Сформувати рядок ps1 типу PAnsiChar ps1 := 'PAnsiChar'; Writeln('ps1 = ', StrPas(ps1)); // 1.2. Сформувати рядок ps2 типу PWideChar ps2 := StrNew('PWideChar'); Writeln('ps2 = ', StrPas(ps2)); // 1.3. Конвертувати PAnsiChar => String - функція StrPas s := StrPas(ps1); Writeln('StrPas(ps1) = ', s); // 1.4. Конвертувати PWideChar => String s := StrPas(ps2); Writeln('StrPas(ps2) = ', s); // 1.5. Звільнити ps2 StrDispose(ps2); // 2. Функція StrPCopy // 2.1. Створити рядок s s := 'String'; Writeln('s = ', s); // 2.2. Виділити фрагмент розміром 20 символів для типу PAnsiChar ps1 := AnsiStrAlloc(20); // 2.3. Скопіювати String => PAnsiChar StrPCopy(ps1, s); Writeln('StrPCopy(s) = ', StrPas(ps1)); // 2.4. Виділити фрагмент для типу PWideChar ps2 := WideStrAlloc(20); // 2.5. Скопіювати String => PWideChar StrPCopy(ps2, s); Writeln('StrPCopy(s) = ', StrPas(ps2)); // 2.6. Звільнити пам'ять, виділену для рядків ps1, ps2 StrDispose(ps1); StrDispose(ps2); Readln; end.
Результат
ps1 = PAnsiChar ps2 = PWideChar StrPas(ps1) = PAnsiChar StrPas(ps2) = PWideChar s = String StrPCopy(s) = String StrPCopy(s) = String
⇑
Споріднені теми
- Функції порівняння двох рядків. Функції StrComp, StrIComp, StrLComp, StrLIComp
- Функції, які змінюють вміст рядка. Функції StrCat, StrLCat, StrLower, StrUpper, StrCopy, StrECopy, StrLCopy, StrMove
- Функції пошуку та отримання інформації про рядки. Функції StrEnd, StrLen, StrPos, StrScan, StrRScan
⇑