Реализация строк типа 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
⇑