Типу данных CHAR соответствуют символьные константы и переменные. Символьная константа есть какой-то символ алфавита, взятый в кавычки. Символьные переменные получают значения символьных констант через оператор присваивания:
ALPFA:='p'; A:='t'; B:='3'; C:=' '; D:=''.
Все символы алфавита образуют множество литер. Каждый символ имеет свой код в ASCII. Это позволяет использовать булевские сравнения: =, <>, <, <=, >, >=.
Данные этого типа описываются с помощью служебного слова CHAR.
Например, переменную ALPFA можно описать VAR ALPFA: CHAR.
ОБЩАЯ ФОРМА ЗАПИСИ: VAR <переменная>: CHAR; |
При работе с данными типа CHAR, если у нас есть последовательность символов, существуют два способа ввода этих символов с клавиатуры.
При первом способе организуется цикл с помощью одного из операторов цикла, внутри которого помещается оператор READLN. При этом способе элементы последовательности вводятся поочередно и после набора на клавиатуре символа необходимо нажать клавишу ввода ENTER. Таким образом, здесь число нажатий клавиши ENTER совпадает с числом вводимых элементов последовательности.
ПРИМЕР 1. С клавиатуры последовательно вводятся символы. Признаком конца ввода является точка. Составить программу выбрасывания групп символов, расположенных между скобками (,). Сами скобки тоже выбрасываются
program SKOBKI;
var c: char; i: integer;
begin
¦ i:=0; read(c);
¦ while c <> '.' do
¦ begin
¦ ¦ if c='(' then i:=1
¦ ¦ else if c = ')' then i:=0
¦ ¦ else if i=0 then write(c);
¦ ¦ read(c);
¦ end;
end.
ПОЯСНЕНИЕ. I = 1 означает, что ранее была прочитана левая скобка, которой пока еще не нашлось парной правой. В этой ситуации прочитанные символы не выводятся на экран. В результате работы этой программы на экране будет представлена строка символов. Здесь вся последовательность символов вводится сразу по первому оператору READ, а затем в цикле из буфера клавиатуры выбираются, анализируются и печатаются символы вне круглых скобок. Например, если вводится последовательность "asg(zx)ytr.", то экран будет выглядеть так:
asg(zx)ytr. - результат работы оператора READ;
asgytr - результат работы оператора WRITE.
В этой программе можно было бы использовать оператор READLN, но тогда после набора каждого символа необходимо нажимать клавишу ввода. Кроме того, на экран будет выводиться не строка символов, а столбец, состоящий из вводимых и отпечатанных элементов. Например, при вводе последовательности "asg(zx)ytr." экран уже будет выглядеть так:
a g x t
a | g |) | t
s | (| y | r
s z y r.
Упорядоченность символов языка используется при написании циклов с параметром, где параметр цикла может пробегать буквенные значения.
ПРИМЕР 2. Программа вывода последовательности букв:
a,ab,abc,...,abc...xyz
program SUITE; РАБОТАПРОГРАММЫ
var c,d: char; a
begin ab
for c:='a' to 'z' do abc
begin abcd
for d:='a' to c do write(d); abcde
writeln(' ');...
end; abcde...xyz
В рассмотренных программах все символы вводились последовательно в процессе работы цикла или хранились временно в буфере клавиатуры. Это не всегда удобно. Поэтому в языках делают строки как последовательность литер. Строку можно задать, как массив литер, при этом в качестве длины строки может выступать верхняя граница массива. Например, VAR HAMLET: ARRAY[1..17] OF CHAR.
Здесь HAMLET - массив литер, компоненты которого имеют тип CHAR; индекс имеет нижнюю границу, равную 1, верхнюю - 17. Для ввода строки в массив HAMLET необходимо организовать цикл из 17 повторений. При каждом повторе этого цикла с клавиатуры вводится очередной символ строки и нажимается клавиша ввода:
Поскольку массивы литер являются обычными массивами, но их компоненты имеют тип CHAR, то они обладают всеми свойствами регулярных массивов. Для извлечения из массива-строки отдельного символа необходимо использовать индекс этого элемента. Например, можно вывести на экран строку HAMLET в обратном порядке с помощью следующего цикла:
for n:=17 downto 1 do write (HAMLET [n]).
ПРИМЕР 3. Дана последовательность символов CHAR: S1,S2,...,S10. Определить, совпадает ли начальная часть с ее конечной частью
program SOWPADENIE;
label 1;
type t = array[1..5] of char;
var s:t; y:char; i:integer;
begin
¦ for i:=1 to 5 do read(s[i]); readln;
¦ for i:=1 to 5 do
¦ begin
¦ ¦ read(y);
¦ ¦ if s[i] <> y then
¦ ¦ begin
¦ ¦ ¦ write('несовпадает');
¦ ¦ ¦ goto 1;
¦ ¦ end;
¦ end;
¦ write('совпадает'); 1:;
end.
ПОЯСНЕНИЕ. В данной программе сначала вводятся по циклу первые пять членов последовательности в массив S[I], причем все пять символов набираются сразу и набор завершается клавишей ввода. Затем с помощью оператора READLN очищается буфер клавиатуры, куда оператор READ(Y) заносит следующие пять символов. Во втором цикле из этого буфера поочередно выбираются символы и сравниваются с ранее введенными. Если все символы совпадают, то печатается текст 'совпадает'. В случае несовпадения печатается текст 'не совпадает' и дальнейшее считывание символов из буфера клавиатуры прекращается.
Чтобы не вводить всю вторую половину символов, а ограничиться только вводом до первого несовпадающего символа, необходимо в программе заменить оператор READ(Y) на оператор READLN(Y).
Наряду с тем положительным, что дают нам массивы литер, они обладают существенным недостатком: их длину нельзя менять во время выполнения программы. Так в рассмотренном примере пункта 2.2 переменная HAMLET есть массив из 17 элементов и, следовательно, туда можно поместить только текст, содержащий ровно 17 символов.
Это не всегда удобно. Хотелось бы иметь такую переменную, в которую можно было бы поместить текст произвольной (но ограниченной) длины. Такую возможность предоставляет тип STRING. Здесь, объявив переменную:
var HAMLET: string[17],
можно ей путем оператора присваивания (а не через цикл) задать значение текста произвольной длины (от 0 до 17).
НАПРИМЕР:
HAMLET:= 'Быть или не быть';
HAMLET:= 'Бедный Йорик';
HAMLET:= ' '; HAMLET:= ''.
Отметим также, что при компиляции программы в случае объявления строки-массива в памяти ЭВМ резервируется место под массив, который должен быть полностью заполнен потом в процессе работы программы. Для типа STRING также резервируется место в памяти того же объема, но здесь необязательно его заполнять целиком. Незаполненные места представлены пробелами.
ОБЩАЯ ФОРМА ЗАПИСИ: | |
TYPE <имятипа> = STRING [N]; | |
VAR <имя переменной>: <имя типа>; | |
или | |
VAR <имя переменной>: STRING [N]; |
Здесь N - целая константа, задающая максимальную длину текста.
Доступ к элементам строки производится с помощью индексов, т.к. в этом типе также все элементы имеют свой (числовой) индекс от 1 до N. В результате получается величина типа CHAR.
НАПРИМЕР: HAMLET:= 'ПРОГРАММА';
HAMLET [1] = 'П'; HAMLET [9] = 'А'.
Строковое выражение состоит из строковых (символьных) констант, переменных, указателей строковых функций и операции конкатенации (склеивания) строк, обозначаемой знаком "+". Строки можно сравнивать. В результате сравнения двух строк, получается истина только в том случае, если сравниваемые строки совпадают посимвольно и имеют одинаковую длину (принадлежат одному и тому же типу).
Текущая длина строковой переменной может быть определена с помощью встроенной функции LENGTH. Например, можно распечатать в цикле значение строки HAMLET:
for c:=1 to length(HAMLET) do write(HAMLET [c]).
Конечно, подобные циклы не надо использовать в реальных программах. Переменные типа STRING могут быть напечатаны с помощью единственного оператора WRITE или WRITELN. Для того, чтобы ввести значение типа STRING, необходимо использовать READLN или READ.
При этом, в отличие от ввода строки-массива, в типе STRING вся строка вводится целиком - клавиша ENTER нажимается один раз после последнего введенного символа.
ПРИМЕР 4. С клавиатуры вводится последовательность слов длиной в 4 символа. Напечатать эти слова, пока не встретится слово STOP.
Программа решения этой задачи зависит от способа введения слов с клавиатуры. Если слова вводятся отдельно друг от друга и после ввода слова сразу идет его печать, то это может быть реализовано с помощью следующего цикла:
repeat
readln(LINE_OF_TEXT); writeln(LINE_OF_TEXT);
until LINE_OF_TEXT = 'STOP',
где LINE_OF_TEXT есть переменная типа STRING[4].
Последовательность слов может быть введена сразу целиком, и для этого совсем необязательно вводить специальную переменную для хранения этого "длинного" слова. Здесь можно воспользоваться буфером клавиатуры для временного хранения всей последовательности слов. Оператор же READ в цикле будет "откусывать" от буфера по 4
символа, а оператор WRITELN - печатать это слово:
repeat
read(LINE_OF_TEXT);
writeln(LINE_OF_TEXT);
until LINE_OF_TEXT = 'STOP'.
Заметим, кстати, что если в программах с подобным циклом еще будут операторы READ, то рекомендуется перед ними сделать очистку буфера с помощью READLN.
Следует отметить также, что в первом случае слова можно вводить и меньшей длины, но работа завершится по набору слова STOP. Во втором случае (при наборе сплошной последовательности слов) выход из цикла будет реализован только при наличии в этой последовательности числа символов, кратных 4, из них последние 4 символа есть слово STOP.
Они введены для облегчения манипуляции со строками. Имеется 8 строковых функций и процедур.
1. ФункцияCONCAT (склеивание).
Синтаксис: concat(S1, S2,..., Sn: string): string.
Возвращает строку, полученную конкатенацией строк S1,...,Sn.
ПРИМЕР: NUMBER:= concat('12','34','50'); NUMBER = '123450'.
2. ФункцияLENGTH(длина).
Синтаксис: length(S: string): integer.
Возвращает длину строки S.
ПРИМЕР: N:= length('345'); N = 3.
3. Функция POS(позиция).
Функция POS в качестве аргументов использует две строки и определяет, содержится ли первая строка во второй. Возвращает номер символа, начиная с которого S входит в T. Если вхождения нет, то возвращает 0.