Символьные данные
Как правило, в программах требуется загружать данные в переменные программы, чтобы использовать эти переменные внутри программы. Данные загруженные в переменную могут быть скопированы в другие переменные или выведены в OUTPUT.
Новые идеи: оператор READ, VAR, символьные переменные, идентификаторы, декларативная часть, INPUT, оператор присваивания, оператор присваивания, символьные литералы, комментарии, аннотированный вывод, эхо ввода.
Переменная с символьным значением может быть описана в декларативной части программы. Декларативная часть программы – начинается заголовком, который содержит стандартное слово VAR (VARiables). Далее следуют описания переменных, которые состоят из идентификаторов и стандартного слова CHAR, которое описывает тип данных переменной. Точка с запятой отделяет декларативную часть от предложения BEGIN.
Например:
VAR
Ch:CHAR;
Описывает декларативную часть где идентификатор Ch. Ch – переменная, CHAR – ее тип данных, в данном случае символьный. Обычно говорят, что в декларативной части мы описали переменную Ch типа CHAR.
Рассмотрим программу CopyChar
Вторая строка программы заключена в фигурные скобки. Это комментарий, он никак не влияет на выполнение программы Паскаль-машиной. Обычно в комментариях располагается информация, необходимая для понимания программы, например, другими программистами.
Наличие грамотных комментариев в программе является элементом хорошего стиля программирования.
PROGRAM CopyChar (INPUT, OUTPUT);
{Выводит первый символ из INPUT в OUTPUT}
VAR
Ch: CHAR;
BEGIN
READ(Ch);
WRITELN(Ch)
END.
INPUT: ABC
OUTPUT: A
В символьную переменную Ch могут быть загружены данные размером в один символ, не более. В программе CopyChar используется оператор READ, который загружает данные из INPUT в переменную Ch. Другими словами, в предложении READ переменной Ch присваивается значение первого доступного символа в INPUT.
Следующее далее оператор WRITELN помещает значение переменной Ch в OUTPUT. Как мы видим, оператор WRITELN способен выводить значение переменных в OUTPUT. В предыдущих примерах оператор WRITELN выводил символьные строки, заметьте, что Ch не заключено в апострофы.
Таблица выполнения для программы CopyChar
INPUT | OUTPUT | Ch | |
PROGRAM CopyChar (INPUT, OUTPUT) VAR Ch: CHAR BEGIN READ(Ch) WRITELN(Ch) END. | ABC ABC ABC ABC ABC | _ _ _ A/_ A | ? A A |
Таблица имеет новые столбцы, показывающие данные в INPUT и значение переменной Ch.
INPUT содержит символьную строку ABC до того как началось выполнение программы. Курсор, изображенный символом подчеркивания, создается первой строкой программы, он отмечает первый символ входной последовательности ABC, который может быть считан программой.
Переменная Ch не существует до выполнения третьей строки программы, содержащей объявление переменной Ch. После выполнения третьей строчки программы переменная Ch создается, но ее значение неопределенно, там может быть любое символьное значение, поэтому мы обозначим его знаком вопроса. Почему так происходит, мы поговорим позднее. Это не означает, что Ch принимает значение '?', мы используем знак вопроса как специальный символ аналогично специальному символу / для маркера конца строки.
Оператор READ(Ch); изменяет состояние INPUT и переменной Ch. В переменную Ch загружается из INPUT символ в позиции курсора (‘A’) и курсор в INPUT перемещается на одну позицию.
Оператор WRITELN выводит содержимое переменной Ch (‘A’) в OUTPUT и перемещает курсор на одну позицию. После выполнения последней строки курсоры в INPUT и OUTPUT пропадают, переменная Ch уничтожается.
Результаты выполнения программы – это изменение INPUT и OUTPUT. Конечно, в INPUT нет новых данных, но OUTPUT содержит результат выполнения программы. Переменная Ch не оставила никаких следов, потому что она существует только во время выполнения программы.
Попробуем проследить несколько вариантов выполнения CopyChar с различным входными данными.
INPUT: ABC
OUTPUT: A
INPUT: A
OUTPUT: A
INPUT: XAABB
OUTPUT: X
Теперь попробуем поменять местами предложения READ и WRITELN
PROGRAM Garbage (INPUT, OUTPUT);
{Писать ничего не прочитав - ошибка}
VAR
Ch: CHAR;
BEGIN
WRITELN(Ch);
READ(Ch)
END.
INPUT: ABC
OUTPUT: ?
INPUT: A
OUTPUT: ?
INPUT: XYZ
OUTPUT: ?
Символ знака вопроса в OUTPUT означает, что результат не определен и в OUTPUT может оказаться любой символ, поскольку при выполнении оператора WRITELN значение переменной Ch еще не определено. Неопределенные данные обычно называются мусором (Garbage).
Таблица выполнения для программы Garbage
INPUT | OUTPUT | Ch | |
PROGRAM Garbage (INPUT, OUTPUT) VAR Ch: CHAR BEGIN WRITELN(Ch) READ(Ch) END. | ABC ABC ABC ABC ABC | _ _ ?/_ ?/_ ? | ? ? A |
Ошибочная программа Garbage преподает нам очень важный урок. Паскаль-программа выполняет инструкции именно в той последовательности, в которой они написаны и программист должен быть аккуратен, чтобы данные не были использованы неправильно или потеряны, как в данном случает, где мы потеряли данные в INPUT и вывели ошибочные данные в OUTPUT.
Программа CopyTwice дает нам еще один пример работы Паскаль-машины, вроде бы как она должна копировать два символа из INPUT в OUTPUT, но этого не происходит.
PROGRAM CopyTwice (INPUT, OUTPUT);
{Ошибочная попытка скопировать два символа из INPUT в OUTPUT}
VAR
Ch: CHAR;
BEGIN
READ(Ch);
READ(Ch);
WRITE(Ch);
WRITELN(Ch)
END.
INPUT: ABC
OUTPUT: BB
INPUT: XXY
OUTPUT: XX
Если построить таблицу выполнения для программы CopyTwice, мы увидим, что первый символ из INPUT считанный в переменную Ch перекрывается вторым символом, считываемым второй инструкцией READ в ту же переменную, поэтому в OUTPUT дважды выводится одно и то же значение – второй символ в INPUT.
PROGRAM Copy2 (INPUT, OUTPUT);
{Копирует первые два символа из INPUT в OUTPUT}
VAR
Letter: CHAR;
BEGIN
READ(Letter);
WRITE(Letter);
READ(Letter);
WRITELN(Letter)
END.
INPUT: ZZ
OUTPUT:ZZ
INPUT:AZURE
OUTPUT:AZ
INPUT:3.14
OUTPUT:3.
В переменной Letter размещаются различные значения в разное время, и не всегда буквы, поэтому она демонстрирует не очень удачный подход к именованию переменных.
Программы могут использовать несколько переменных.
PROGRAM CopyReversed (INPUT, OUTPUT);
{Копирует первые два символа из INPUT в OUTPUT в обратном порядке}
VAR
Ch1, Ch2: CHAR;
BEGIN
READ(Ch1, Ch2);
WRITELN(Ch2, Ch1)
END.
INPUT:ZA
OUTPUT:AZ
INPUT:AZURE
OUTPUT:ZA
Когда в операторах READ WRITE встречается более чем один элемент данных, эти предложения ведут себя как последовательность операторов READ и WRITE с одним элементом данных. Вариантов компоновки операторов WRITE и READ может быть множество.
READ(Ch1, Ch2) эквивалентно READ(Ch1); READ(Ch2)
WRITELN(Ch1, Ch2) эквивалентно WRITE(Ch1); WRITE(Ch2); WRITELN