Выражения и оператор присваивания
Чтобы задать переменной какое-либо значение, используется оператор присваивания.
<оператор присваивания>::=<имя переменной> := <выражение>
В левой части оператора присваивания стоит идентификатор переменной, а в правой — выражение, результат вычисления которого должен стать значением этой переменной. Между ними указывается составной символ операции присваивания :=. Например, в результате выполнения оператора 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