Оператор присваивания |
Оператор присваивания выполняет выражение, стоящее в правой части оператора, и присваивает результат вычислений элементу, имя которого указано в левой части. Если выражение в правой части не может быть вычислено, то левой части присваивается значение по умолчанию: ноль для числовых переменных, пустая строка - для строковой переменной.
<оператор-присваивания> = <имя> := <выражение>;
Выражение нельзя вычислить, например, в том случае, если оно содержит обращение к немодифицированному полю таблицы, в которой нет позиции.
<имя> - идентификатор переменной, поле таблицы, элемент массива.
<выражение> - выражение, результат вычисления которого присваивается.
Элемент, имя которого указано в левой части оператора, и выражение в правой части оператора должны иметь один тип за исключением случая, когда элемент имеет вещественный тип, а выражение - целочисленный.
Оператор присваивания можно использовать в вычисляемых выражениях (начиная с Атлантис 5.1.12). Приоритет оператора присваивания самый низкий т.е. выполняется в последнюю очередь. Значением оператора присваивания является значение выражения слева от знака присваивания после выполнения операции. Разрешено каскадное присваивание.
Каскадное присваивание не даёт никакого выигрыша в скорости интерпретации.
Присваивание не может быть использовано как var-параметр функции.
Начиная с Атлантис 5.3.05 оператор в качестве результата возвращает не значение вычисляемого выражения, а ссылку на переменную, которой присваивается результат.
При использовании оператора присваивания необходимо иметь в виду, что:
передача оператора присваивания в качестве var-параметра запрещена;
разрешено использовать значение результата работы оператора присваивания внутри другого оператора присваивания;
явное присваивание значения результату работы оператора присваивания запрещено;
прочие виды присваивания результату работы оператора присваивания не рекомендуются к использованию;
использование нескольких присваиваний одной и той же переменной в пределах одного вычисляемого выражения - сложная для понимаюия конструкция, при использовании которой необходимо внимательно вчитываться в код.
В случае, когда необходимо отделить оператор присваивания от вычисляемого выражения, необходимо использовать скобки. В противном случае компилятор будет считать, что производится операция присваивания всему выражению, которое стоит в левой части.
Например:
j := 1 + ( i := 5 );
но не
j := 1 + i := 5;
т.к. присваивание значения выражению "j := 1 + i" запрещено.
Допускается опускать скобки при создании конструкции из нескольких идущих подряд операторов присваивания, например:
j := i := 6;
Пример 1.
Employee.DayIn := Cur_Date;
Пример 2.
a := b := c := d := 0; // эквивалентно d := 0; с := d; b := c; a := b;
Пример 3. Явное использование присвоения
Меssage(j := 2); // выдаст на экран сообщение "2" // в предыдущей строке выполняется код, аналогичный j := 2; Меssage(j); // но не j := 2; Меssage(2); Message(i := 2 + 1); // выдаст на экран "3" и в i положит 3. Message(i); // выдаст на экран "3" // В следующей строке оператор присваивания отделен от вычисляемого выражения скобками: Message((i := 2) + 1); // выдаст на экран "3", а в i положит 2. Message(i); // соответственно, выдаст на экран "2" Message(i * (i := 6)); // выдаст на экран "36" (6 * 6)
Пример 4. Вложенное использование
После выполнения кода переменная i примет значение "3".
Message(i := 1 + (i := 2)); // выдаст на экран сообщение "3"
Пример 5. Многократная вложенность присвоения
Пример содержит корректный но нечитабельный код. Приводится для иллюстрации работы оператора присвоения. Использовать подобный код в реальных программах категорически не рекомендуется.
var arr : array[1..5] of byte; arr[arr[arr[arr[arr[1]:=4]:=2]:=5]:=3]:=1;
Код порождает массив, как-бы инициализированный своими же индексами и циклически сдвинутый на 2 элемента:
arr[1] = 4 arr[2] = 5 arr[3] = 1 arr[4] = 2 arr[5] = 3
Пример 6. Неожиданный результат
Пример содержит корректный но нечитабельный код. Приводится для иллюстрации работы оператора присвоения. Использовать подобный код в реальных программах категорически не рекомендуется.
i := 1; i := i := i * 2 + (i := i * 5);
Данное выражение аналогично выражению:
i := (i := i * 2 + (i := i * 5));
которое аналогично следующему:
i := i * 2 + (i := i * 5);
В процессе выполнения часть (i * 2) возвращает 2, т.к. i до этого было 1. Часть (i := i * 5) возвращает 5, т.к. значение переменной i не менялось в процессе выполнения (i * 2). После этого значение "5" временно заносится в переменную i, производится сложение i с "2", результат записывается в i.
В результате i принимает значение 7.
Теперь заключим первое присвоение в скобочки. Полученный код имеет вид:
i := 1; i := (i := i * 2) + (i := i * 5);
Выполнение этого кода состоит из 4-х этапов:
Выполняется часть (i := i * 2). Переменной i присваивается значение 2, оператор же присваивания возвращает i (но не 2!).
Выполняется часть (i := i * 5). Т.к. переменная i уже имеет значение 2, то в результате получается 10, что и присваивается переменной i. Оператор возвращает опять же i, (но не 10, а именно i, которая в этот момент равна 10).
Вызывается оператор суммирования, который складывает i c i. Т.к. ранг у присваивания самый высокий, то на момент суммирования переменная i несет в себе значение 10. Поэтому оператор суммирования возвращает 20 (уже численное значение).
Переменной i присваивается 20.
Начиная с Атлантис 5.3.05 оператор присваивания в качестве результата возвращает не значение вычисляемого выражения, а ссылку на переменную, которой присваивается результат.
Использование оператора присваивания в вычисляемых выражениях и каскадное присваивание доступны начиная с Атлантис 5.1.12