Символы и строки
Строковые типы данных
В Lazarus основным строковым типом является String (англ. string - строка). На форму нашего проекта разместите еще одну кнопку. Её обработчик будет выглядеть так:
procedure TfMain.Button2Click(Sender: TObject);
var
s: String;
begin
s:= 'Это строка из пяти слов!';
ShowMessage(s);
end;
Как видите, поскольку строка в Lazarus имеет формат UTF8, то никаких особых ухищрений для работы со строками тут не нужно, в переменную типа String можно записать любой, в том числе и русский текст. Размер строки String неограничен, однако имеется возможность жестко задать размер. Такой способ используется, когда вы точно знаете, что больше данного размера строка не будет. В этом случае размер указывается после ключевого слова String в квадратных скобках, например:
var
MyStr: String[50];
В переменную MyStr можно записать до 50 символов. Максимальный размер строки, который можно жестко задать таким способом - 255 символов. Однако имеются в виду символы ASCII, то есть английские, однобайтовые. Пример:
var
s: string[7];
begin
s:= 'Привет!';
ShowMessage(s);
end;
Данный пример ошибки не вызовет, однако сообщение выйдет не полностью, а обрезанным: "При". То есть, три первых буквы заняли 6 байт, четвертая уже не уместилась. В данном случае будет правильным указать размер не 7, а 14 - по удвоенному количеству букв. Впрочем, на практике обычно применяют тип String без ограничений, в этом случае строка обрабатывается правильно.
Имейте в виду, что тип String является динамичным, то есть, заранее память для него не выделяется. Строго говоря, выделяется память на указатель строки, а не на саму строку. Физически строке выделяется необходимая память только в момент присвоения ей какого-то значения. Однако нередко возникает необходимость очистить такую строку. Для этого достаточно присвоить ей пустые кавычки, без пробелов и без каких-либо других символов:
s:= '';
В этом случае, строке присваивается значение Nil, то есть ноль, ничего, и строка становится пустой.
Строковой переменной можно присваивать значения символьных переменных или констант, например:
var
c: Char;
s: String;
begin
c:= 'Z';
s:= c;
Помимо String в Lazarus есть и другие строковые типы.
| ShortString | Короткая строка, которая может содержать максимум, 255 ASCII-символов. То есть, ShortString - это String[255]. |
| AnsiString | Строка неограниченной длины из ANSI-символов. Фактически всё, что мы говорили про String, относится именно к AnsiString. Отдельного типа String как такового, не существует, это просто сокращенная запись AnsiString. Однако это зависит от настроек. Есть в Паскале такие переключатели, которые еще называют директивы компилятора. Такие директивы подобно комментариям, заключают в фигурные скобки, а первым символом должен быть символ доллара. Тип, который будет использован в качестве String, зависит от директивы {$H}. Если она выключена {$H-}, то при указании типа String будет подразумеваться тип ShortString. Если она включена {$H+} - то AnsiString. По умолчанию переключатель включен, вы сможете это увидеть в третьей строке модуля, пролистав его код вверх:
unit Main;
{$mode objfpc}{$H+}
На практике короткую строку используют крайне редко, ведь если нужна короткая строка, то ее размер можно указать явно. Поэтому данный переключатель исправлять вручную обычно не приходится. Давайте считать, что String и AnsiString - это одно и то же. |
| PChar | Строка в стиле C/C++ с нулевым символом в конце. Такой тип строк используется в функциях Windows API, поэтому имеет поддержку и в Lazarus. Что это за строка такая? Дело в том, что обычные строки динамические, то есть фактически переменная типа String - это указатель на строку. Эта переменная хранит физический адрес строки в памяти, и количество занимаемых ею байт. Строка типа PChar устроена несколько иначе. Это тоже указатель на строку, но он не хранит её размер. А как тогда компилятору знать, сколько байт нужно считывать при обращении к такой переменной? Дело в том, что в строках типа PChar завершающим всегда будет нулевой символ, то есть, символ #0. Если такой символ поместить внутри строки, то компилятор не будет читать всю строку. Встретив символ #0, он решит, что строка закончена. Мы будем использовать PChar, когда дойдем до функций WinAPI. |
Как правило, строкам одного типа можно присваивать значения строк другого типа, компилятор автоматически преобразует текст. Исключение составляют строки PChar, тут нам придется делать преобразование вручную, с помощью функции PChar(). Исправим обработчик второй кнопки:
procedure TfMain.Button2Click(Sender: TObject);
var
s1: String; //он же AnsiString
s2: ShortString;
s3: PChar;
begin
s1:= 'Это строка из пяти слов!';
//Теперь присвоим тот же текст в ShortString:
s2:= s1;
//Тот же текст в PChar. Для преобразования строки в этот тип
//используем функцию PChar():
s3:= PChar(s1);
//Соберем сообщение из трех разнотиповых строк. Каждый тип
//выведем в отдельной строчке:
ShowMessage(s1 + #13 + s2 + #13 + s3);
end;
Сохраните проект, скомпилируйте и запустите. При нажатии на вторую кнопку у вас выйдет сообщение из трех строк
Имеются еще типы UnicodeString и WideString, оба типа содержат двухбайтовые символы. Но работать с такими типами неудобно - возникают проблемы с кириллицей, для нас гораздо удобней простой String. Поэтому рассматривать данные типы мы не будем.
Резюмируем некоторые положения:
- Три основных строковых типа: AnsiString, ShortString и PChar.
- Обычно указывают тип String. Если переключатель {$H} включен (по умолчанию), то используется тип AnsiString. Иначе - ShortString.
- Строке можно присвоить либо текст, заключенный в одинарные кавычки, либо содержимое другой строковой переменной, например:
s1:= 'Текст';
s2:= s1;
- Строке типа PChar можно присвоить либо текст, либо содержимое другой строковой переменной. Но если тип этой переменной отличается, то нужно сделать преобразование функцией PChar():
var
s: String;
pc: PChar;
begin
s:= 'Текст';
pc:= 'Текст'; //присвоили текст
pc:= PChar(s); //присвоили преобразованное значение переменной s