Учебный центр "ANIT Texno Inform"
Опубликован: 25.06.2014 | Доступ: свободный | Студентов: 2595 / 849 | Длительность: 24:39:00
Специальности: Программист
Лекция 5:

Символы и строки

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >

Строковые типы данных

В 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
    
< Лекция 4 || Лекция 5: 12345 || Лекция 6 >
Инга Готфрид
Инга Готфрид
Александр Скрябнев
Александр Скрябнев

Через WMI, или используя утилиту wmic? А может есть еще какие более простые пути...