Выражения и оператор присваивания

Чтобы задать переменной какое-либо значение, используется оператор присваивания.

 

<оператор присваивания>::=<имя переменной> := <выражение>

 

В левой части оператора присваивания стоит идентификатор переменной, а в правой — выражение, результат вычисления которого должен стать значением этой переменной. Между ними указывается составной символ операции присваивания :=. Например, в результате выполнения оператора x := 1 + 2 переменная х будет иметь значение, равное 3.

Отметим, что в левой части оператора может находиться только переменная, объявленная в подразделе var, или типизированная константа.

На Рис. 1 приведены еще три примера работы оператора присваивания. На рисунках обозначены переменные, связанные с ними ячейки памяти и их содержимое до и после выполнения оператора присваивания.

Рис. 1. Иллюстрация работы оператора присваивания

Из рисунка видно, что оператор присваивания, по обе стороны которого указаны переменные, создает копию значения правой переменной в левой. Кроме того, если в выражении справа присутствует переменная, указанная слева, вычисление выражения происходит относительно старого значения переменной.

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

Допустим, требуется однотипные переменные а и b обменять значениями. Для этого будем использовать вспомогательную переменную с.

 

Оператор Действие
1 c := a Запоминаем значение а в переменной с
2 a := b Присваиваем переменной а значение b
3 b := c Присваиваем переменной b значение переменной с, т.е. "старое" значение а

 

Схема обмена значениями представлена в таблице.

 

Состояние переменных а b c
До выполнения операторов 10 14 ?
После выполнения 1-го оператора 10 14 10
После выполнения 2-го оператора 14 14 10
После выполнения 3-го оператора 14 10 10

 

Выражения, стоящие в правой части оператора присваивания, могут содержать операнды, т.е. функции, переменные или константы, и знаки операций, например *, + и другие. Операции в Паскале можно разделить на арифметические, логические, операции отношения и побитовые операции.

Арифметические операции могут быть унарными (операции над одним операндом) и бинарными (операции над двумя операндами).

Существует всего две арифметические унарные операции: + и –. Операция + не влияет на значение операнда, а операция меняет знак операнда на противоположный. В языке Паскаль используется шесть арифметических бинарных операций: + (сложение), – (вычитание), * (умножение) и / (деление), а также операции целочисленного деления div и вычисления остатка от целочисленного деления mod. Результатом вычисления выражения a div b будет целая часть числа, полученного делением а на b, а результатом вычисления выражения a mod b будет остаток от деления а на b.

 

Выражение Результат Выражение Результат
47 div 5 9 47 mod 5 2
12 div 5 2 12 mod 5 2
125 div 10 12 125 mod 10 5
7 div 9 0 7 mod 9 9

 

Тип результатов сложения, вычитания и умножения зависит от типа операндов: если все операнды целого типа, то и результат будет иметь также целый тип, если же хотя бы один из операндов имеет вещественный тип, то результат будет вещественным. Операция деления всегда дает результат вещественного типа. Операнды и результаты операций div и mod могут быть только целого типа. Если целочисленное выражение присваивается вещественной переменной, происходит автоматическое преобразование типа результата из целого в вещественный. Например, если переменной х вещественного типа, присваивается выражение 10 div 5, то она примет вещественное значение 2.0.

Логические операции предназначены для работы с операндами логического типа. Подробно эти операции будут рассмотрены в теме «Условный оператор».

Операции отношения предназначены для сравнения двух однотипных величин. Результат этих операций имеет логический тип. Все эти операции являются бинарными. В Паскале определены шесть операций отношения: > (больше), < (меньше), = (равно), <> (не равно), >= (больше или равно), <= (меньше или равно). Результат операции равен true, если соответствующее отношение выполняется, и false — в противном случае. Операндами могут быть значения любых простых типов, включая char.

Порядок вычисления выражения зависит от приоритетов входящих в него операций. Если в выражении нет скобок, то сначала выполняются операции с наивысшим приоритетом, далее с более низким. Если в выражении присутствуют несколько операций с одинаковым приоритетом, то они выполняются слева направо. Наивысший приоритет имеют операции вычисления значений функций, затем следуют унарные операции + и –, за ними — операции умножения, деления, div и mod, далее операции сложения, вычитания, самый низкий приоритет имеют операции отношения.

Для повышения приоритета операции необходимо пользоваться круглыми скобками: выражения в скобках вычисляются в первую очередь.

Например, результатом вычисления выражения a + b * c при а = 2, b = 3 и с = 4 будет 14, так как сначала выполняется операция умножения, а затем сложения. Результатом вычисления выражения ( a + b )* c при тех же значениях операндов будет 20, так как первой выполняется операция в скобках — сложение.

В выражении могут быть использованы и вложенные скобки. Правила применения скобок здесь такие же, как и в обычной математике.

Зная правила описания переменных, синтаксис оператора присваивания и правила вычисления выражений, можно написать простейшую законченную программу на Паскале, например, программу вычисления среднего арифметического трех целых чисел a, b и c.

program average;

{Программа вычисляет среднее арифметическое чисел a, b и c }

var

a,b,c : integer;

s : real;

begin

a:=1;

b:=3;

c:=8;

{Вычисление среднего арифметического}

s:=(a+b+c)/3;

end.

Ввод-вывод

Итак, вы уже можете написать простую программу, которая может быть выполнена компьютером. Однако мы не сможем менять числа а, b и с, не изменяя саму программу, и не увидим результат ее работы, поскольку в программе не предусмотрены ввод и вывод данных.

Ввод и вывод информации в Паскале производятся не при помощи операторов, а с использованием стандартных процедур. Они описаны в стандартном модуле System, входящем в среду Паскаля, поэтому их можно использовать без дополнительных описаний и объявлений. Отличие стандартных процедур от операторов заключается в том, что они имеют свои параметры, указанные в круглых скобках, и их имена не являются зарезервированными словами.

Вводить данные в Паскале можно при помощи двух стандартных процедур — read и readln. Процедура read используется следующим образом: сначала указывается ее имя, а затем в круглых скобках указывается список переменных, значения которых необходимо ввести. Переменные отделяются друг от друга запятыми.

Синтаксическая диаграмма вызова процедуры read для ввода данных со стандартного устройства ввода, как правило, с клавиатуры приведена на Рис. 2.

Рис. 2. Синтаксическая диаграмма вызова процедуры read для ввода с клавиатуры

При выполнении процедуры read ожидается ввод перечисленных в процедуре значений. Вводимые значения отделяются друг от друга одним или несколькими пробелами или переходом на следующую строку и присваиваются по очереди указанным в скобках переменным. Например, при выполнении строки программы read(a,b,c,x); будет ожидаться ввод четырех значений. Первое значение будет присвоено переменной а, второе — переменной b, третье — переменной с и четвертое — переменной х. Значения должны иметь вид констант, допустимых для переменных типа, которому принадлежат соответствующие переменные. При вводе значений символьного типа кавычки не ставятся. Например, если а и b описаны как переменные типа integer, сchar, а x — real, то при вводе последовательности значений

4 4.5 z 4

возникнет аварийная ситуация, так как мы пытаемся вещественное число 4.5 присвоить переменной типа integer b. Последовательность значений

5 60

z

567.е-2

является правильной.

Ввод значений перечисляемого типа почти во всех современных версиях Паскаля невозможен (то же относится и к выводу).

Процедура readln используется так же, как и процедура read с тем лишь отличием, что выполнение процедуры readln завершается только после нажатия на клавишу "возврат каретки" (<Enter>),

Рассмотрим эту разницу на примере. При выполнении следующего фрагмента программы

read(a,b);

read(c);

и при вводе данных

4 5 1

переменной а присвоится значение 4, переменной b — 5, а переменной с — 1. В случае же фрагмента

readln(a, b);

readln(c);

при вводе данных таким же образом переменной а присвоится значение 4, переменной b — значение 5. После этого ожидается ввод значения с на новой строке. Значение 1 будет проигнорировано.

Часто процедура readln без параметров ставится в конце программы для задержки до нажатия клавиши "возврат каретки". Однако если предыдущий ввод запрашивался процедурой read, задержки не будет. Эта особенность служит источником многочисленных недоразумений у начинающих программистов.

Вывод данных обеспечивается двумя стандартными процедурами write и writeln. Параметрами этих процедур могут быть константы или переменные любого простого типа, за исключением перечисляемого. Синтаксическая диаграмма вызова процедуры write приведена на Рис. 3. Например, при вызове

write('Значение а равно ', а, ', значение b+1 - ', b+1)

при а, равном -23, и b, равном 3, на экране появится текст

Значение а равно -23, значение b+1 – 4

Рис. 3. Синтаксическая диаграмма вызова процедуры write для вывода на экран

Числа вещественных типов по умолчанию выводятся в экспоненциальной форме с одним знаком до запятой и с использованием десятичного порядка. Числа, выведенные на экран в таком виде, воспринимаются обычным пользователем далеко не лучшим образом. Для того, чтобы вывести вещественное число в общепринятой форме, задается формат вывода. Процедура вывода форматированного вещественного значения имеет вид:

write(x:n:m),

где х — переменная вещественного типа, а n и m — выражения целого типа, характеризующие ширину поля вывода. Выражение n означает, что все число будет выравниваться по правому краю поля из n символов (недостающие символы слева заменяются пробелами), выражение m означает, что число будет выводиться с m знаками после запятой.

При этом будет происходить округление абсолютной величины числа. Предположим, что необходимо вывести переменную х вещественного типа. При использовании вывода write(x) (пусть х равно 34.561) мы получим на экране число 3.4561000000Е+01. В случае записи

write(x:8:2)

при х, равном 34.561, на экране появится число 34.56, которому будут предшествовать три пробела, а при х, равном 34.567, — число 34.57 с тремя пробелами слева. Если при заданной длине дробной части число занимает больше n позиций, то будет выведено ровно столько позиций, сколько занимает число, никакого сообщения об ошибке не будет. Если использовать процедуру в форме write(x:n), то вещественное число будет выведено в экспоненциальной форме, но выровненным по правому краю поля шириной в n символов.

Формат вывода можно использовать и для вывода значений других типов, но при этом можно использовать только форму с одним форматом: write(a:n). В этом случае выводимое значение будет выравниваться по правому краю поля шириной в n символов.

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

Процедуры write и writeln используются не только для вывода результата, но и для вывода различных сообщений или запросов. Например, при вводе данных вызов одной лишь процедуры ввода приведет к тому, что программа будет ожидать от пользователя ввода значений, однако пользователь далеко не всегда знает, что ему необходимо делать. Поэтому перед процедурой ввода вызывается процедура вывода запроса на ввод, например:

write('Введите целое число: '); read(a);

В этом случае на экран будет выдан запрос "Введите целое число: ", и только потом программа будет ожидать от пользователя ввода числа.

Вернемся теперь к нашей первой программе, вычисляющей среднее арифметическое трех чисел. Добавим в нее ввод чисел а, b и с и вывод результата. Для ввода воспользуемся процедурой readln, для вывода — процедурой write, а для задержки до нажатия клавиши "возврат каретки" — процедурой readln без параметров. Обратите внимание на вывод результата: в параметрах процедуры writeln чередуются через запятую строковые константы и переменные целого и вещественного типов. Это обеспечивает вывод не какого-то результата не известных пользователю вычислений, а вывод вместе с пояснением, что же именно означает выводимый результат.

program average;

{Программа вычисляет среднее арифметическое чисел a, b и с}

var

a,b,c : integer;

s : real;

begin

{ввод чисел a, b и с}

write('Введите первое число:');

readln(a);

write('Введите второе число:');

readln(b);

write('Введите третье число:');

readln(c);

{вычисление среднего арифметического}

s := (a+b+c)/3;

{вывод результата}

writeln('Среднее арифметическое чисел ',а,', ',b,' и ',с,' равно', s:6:3);

readln;

end.

 

Приведем протокол работы этой программы.

Введите первое число: 4

Введите второе число: 6

Введите третье число: 3

Среднее арифметическое чисел 4, 6 и 1 равно 4.333