Символы и строки
Строковые типы данных
В 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