Строковый тип данных в 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.
Задания для дополнительной или самостоятельной работы:
- Вводятся две строки, программа должна сообщать, какая из них длиннее.
- Используя цикл, выведите символы строки в обратном порядке.
- На экран выводится слово, у которого одна буква замаскирована звездочкой. Программа должна спрашивать у пользователя, какая там должна быть буква, пока он не введет правильный ответ.