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

Обновлено: 19.04.2026

Вспомним про массивы. До этого мы создавали только численные массивы. Однако ничего не мешает создать массив символов:

const
    N = 10;
var
    ch: array[1..N] of char;
    i: byte;
begin
    for i:=1 to N do
        read(ch[i]);

    for i:=1 to N do
        write(ch[i]);
    writeln;
end.

Пример выполнения:

one two three
one two th

В примере введенная строка длиннее, чем длина массива. Однако лишние символы не считывались, потому что цикл закончил свою работу раньше.

Из этого можно сделать вывод, что если необходимо хранить целую строку, а не один символ, следует использовать переменную, объявленную как массив символов. Это "понимает" и язык программирования Pascal, в котором реализована возможность как заполнять символьный массив одним упоминанием переменной, так и выводить таким же способом. С числами так делать было нельзя. Поэтому программу выше можно сократить до такой:

const
    N = 10;
var
    ch: array[1..N] of char;
begin
    readln(ch);
    writeln(ch);
end.

Однако хранение строк в обычных массивах имеет ряд недостатков. Одним из них является неизменность длины массива. В нашем примере строка должна быть ровно из 10-ти символов. Если вы нажмете Enter раньше, в массиве останутся нули (в случае char это символы с кодом 0, в выводе вы их не увидите), но length(ch) все-равно выдаст 10. Чтобы хранить истинную длину строки, пришлось бы вводить отдельную переменную. Поэтому для решения этой и других проблем во многие языки программирования был добавлен полноценный строковый тип данных.

В Паскале есть несколько строковых типов, и в этом уроке речь пойдет о типе string, или shortString (далее используйте последний, если в вашей среде разработки string — это "длинные" строки). В Паскале переменные коротких строк по-умолчанию занимают по 256 байтов памяти. При этом первый байт хранит длину строки. По-сути короткие строки так и остаются массивами, но индексация в них начинается с нуля. Поэтому первый байт имеет индекс 0.

var
    s: string;
begin
    writeln(sizeof(s));  // 256
    writeln(length(s));  // 0
    writeln(ord(s[0]));  // 0
    s := 'Hello World!';
    writeln(sizeof(s));  // 256
    writeln(length(s));  // 12
    writeln(ord(s[0]));  // 12
end.

Поскольку максимальное десятичное значение, которое можно хранить в одном байте, — это 255, то при таком способе хранения длины строка просто не может быть длиннее 255 символов. Длина строки через обращение по индексу возвращается в виде символа (ведь строка — это массив символов, а не чисел). Поэтому чтобы получить код символа, который обозначает длину строки, нужна функция ord. Хотя максимально возможная длина строки 255 символов, и память выделяется под максимальный размер, с помощью первого байта мы точно знаем каков ее реальный размер.

Что делать, если необходима строка длиннее 255 символов? Для таких целей в Pascal есть другие строковые типы, например WideString, переменная которого является указателем, и принцип работы с памятью там иной. При определенных настройках компилятора string может вести себя как AnsiString (подобна WideString).

Создайте строковую переменную, присвойте ей строку, введенную с клавиатуры. Выведите на экран саму строку и ее длину.

Теперь посмотрим, сможем ли мы работать с русскими словами:

var
    p, r: string;
begin
    p := 'Привет';
    readln(r);
    writeln(p, ', ', r, '!');
    writeln('p=', length(p));
    writeln('r=', length(r));
    writeln(sizeof(r));
end.
Мир
Привет, Мир!
p=12
r=6
256

Максимальная длина стоки остается та же, но почему-то на каждый русский символ тратится по два байта, и строка получается длиннее (при кириллических кодировках такого "эффекта" не будет). Все дело в кодировке UTF-8, которая часто используется как в редакторе кода, так и в терминале. В ней под символы таблицы ASCII отводится 1 байт, и поэтому длины английских строк измерялись правильно, а под русские — два байта.

Когда происходит запись строки в байты памяти, отведенной под переменную типа string, то код каждой русской буквы занимает 2 байта. Когда происходит считывание значения из переменной типа string, то она "отдает" все свои байты, а то, как они будут интерпретированы терминалом, редактором или другими программами саму переменную не волнует. Консоль переводит эти байты в кодировку UTF-8 и поэтому правильно отображает буквы. Таким образом, чтобы работать с русскими словами, кодировки вашего редактора и командной строки должны совпадать.

Если заранее известно, что длина строки будет меньше 255 символов, то программист может сэкономить память и сам задать максимальную длину строки.

const
    N = 50;
var
    d: string[N];
    e: string[15];

Проверьте, что хранится в первом байте строки, максимальная длина которой устанавливает вручную. Чтобы будет с символами, которые уже не помещаются в эту строку?

Операции над строками

Строки можно присваивать друг другу. Если максимальная длина переменной слева меньше длины присваиваемой строки, то лишние символы справа отбрасываются:

s1 := 'this is text';
s2 := s1;

Строки можно объединять с помощью операции конкатенации, которая обозначается знаком +:

s1 := 'John';
s2 := 'Black';
s1 := s1 + ' ' + s2;

Строки можно сравнивать друг с другом с помощью операций отношения:

'abc' > 'ab' (true)
'abc' = 'abc' (true)
'abc' < 'abc ' (false)

При сравнении строки рассматриваются посимвольно слева направо, при этом сравниваются коды соответствующих пар символов. Строки равны, если они имеют одинаковую длину и посимвольно эквивалентны. В строках разной длины существующий символ всегда больше соответствующего ему отсутствующего символа. Меньшей будет та строка, у которой меньше код первого несовпадающего символа (вне зависимости от максимальных и текущих длин сравниваемых строк).

К отдельному символу строки можно обращаться как к элементу массива символов, например s[3]. Таким образом можно осуществлять коррекцию любого символа строковой переменной. Символ строки совместим с типом char, их можно использовать в выражениях одновременно:

s[3] := 'h';
writeln(s[10] + 'r');

Нулевой элемент строковой переменной можно корректировать. При этом будет изменяться текущая длина строки. Например, выражение str[0] := #50 устанавливает текущую длину равной 50.

Задания для дополнительной или самостоятельной работы:

  1. Вводятся две строки, программа должна сообщать, какая из них длиннее.
  2. Используя цикл, выведите символы строки в обратном порядке.
  3. На экран выводится слово, у которого одна буква замаскирована звездочкой. Программа должна спрашивать у пользователя, какая там должна быть буква, пока он не введет правильный ответ.