Дополненное задание - Augmented assignment
Расширенное присваивание (или составное присваивание ) - это имя, данное определенным
операторам присваивания в определенных языках программирования (особенно тех, которые являются производными от C ). Расширенное присваивание обычно используется для замены оператора, в котором оператор принимает переменную в качестве одного из своих аргументов, а затем присваивает результат обратно той же переменной. Простой пример расширен до . Подобные конструкции часто доступны для различных бинарных операторов.
x += 1
x = x + (1)
В общем, в языках, предлагающих эту функцию, большинство операторов, которые могут принимать переменную в качестве одного из своих аргументов и возвращать результат того же типа, имеют эквивалент расширенного присваивания, который присваивает результат обратно переменной на месте, включая арифметические операторы, битовый сдвиг операторы и побитовые операторы .
Обсуждение
Например, следующий оператор или его вариант можно найти во многих программах:
x = x + 1
Это означает «найти число, хранящееся в переменной x , прибавить к нему 1 и сохранить результат сложения в переменной x ». Каким бы простым это ни казалось, он может иметь неэффективность, так как местоположение переменной x нужно искать дважды, если компилятор не распознает, что две части выражения идентичны: x может быть ссылкой на некоторый элемент массива или другая сложность. Для сравнения, вот версия с расширенным назначением:
x += 1
В этой версии нет оправдания тому, что компилятор не смог сгенерировать код, который ищет местоположение переменной x только один раз и изменяет его на месте, если, конечно, машинный код поддерживает такую последовательность. Например, если x - простая переменная, последовательность машинного кода может выглядеть примерно так:
Load x Add 1 Store x
и для обеих форм будет создан один и тот же код. Но если есть специальный код операции, это может быть
MDM x,1
означает «Изменить память», добавив 1 к x, и приличный компилятор сгенерирует один и тот же код для обеих форм. Некоторые машинные коды предлагают операции INC и DEC (для добавления или вычитания единицы), другие могут допускать константы, отличные от единицы.
В более общем плане форма
x ?= expression
где ? обозначает некоторый оператор (не всегда + ), и не может быть никаких специальных кодов операций, которые могут помочь. По-прежнему существует вероятность того, что, если x - сложная сущность, компилятору будет рекомендовано избегать дублирования при доступе к x , и, конечно, если x - длинное имя, потребуется меньше ввода. Последнее было основой аналогичной функции в компиляторах ALGOL, предлагаемых через системы Burroughs B6700 , с использованием символа тильды для обозначения переменной, которой назначается, так что
LongName:=x + sqrt(LongName)*7;
станет
LongName:=x + sqrt(~)*7;
и так далее. Это более общий характер, чем просто x:=~ + 1;
создание оптимального кода, оставшееся прерогативой компилятора.
Семантика
В языках программирования, ориентированных на выражения, таких как C, присваивание и расширенное присваивание - это выражения, которые имеют значение. Это позволяет использовать их в сложных выражениях. Однако это может привести к появлению последовательностей символов, которые трудно читать или понимать, и, что еще хуже, опечатка может легко привести к другой последовательности тарабарщины, которая, хотя и принята компилятором, не дает желаемых результатов. В других языках, таких как Python, присваивание и расширенное присваивание являются операторами, а не выражениями, и поэтому не могут использоваться в сложных выражениях. Например, следующий допустимый C, но не действительный Python:
a += b += c
Как и присваивание, в этих языках расширенное присваивание является формой правоассоциативного присваивания .
В отличие от C, выражения составного присваивания C ++ оценивают lvalue . Значение lvalue позволяет записать его слева от другого оператора присваивания:
int x = 11;
(x *= 2) += 3; // Sets x to 25
Вычисленные места назначения
В таких языках, как C, C ++ и Python, расширенному назначению, в котором место назначения включает вызовы функций, предписывается вызывать функции только один раз. Т.е. в заявлении:
my_array[f1()] += 1
Функция f1
имеет мандат быть вызван только один раз.
Если язык реализует расширенное присвоение путем расширения макроса до:
my_array[f1()] = my_array[f1()] + 1
Затем f1
вызывается дважды.
По языку
C потомки
В C , C ++ и C # оператор присваивания = , который дополняется следующим образом:
Оператор | Описание |
---|---|
+=
|
Добавление |
-=
|
Вычитание |
*=
|
Умножение |
/=
|
Разделение |
%=
|
Модуль |
<<=
|
Левый битовый сдвиг |
>>=
|
Правый битовый сдвиг |
&=
|
Побитовое И |
^=
|
Побитовое исключающее ИЛИ |
|=
|
Поразрядное включающее ИЛИ |
Каждый из них на указанных языках называется составным оператором присваивания .
Поддерживающие языки
Следующий список, хотя и не полный и не исчерпывающий, перечисляет некоторые из основных языков программирования, поддерживающих расширенные операторы присваивания.
|
|
Смотрите также
- Операторы увеличения и уменьшения - частный случай расширенного присваивания на 1
- Расширенные арифметические операции IEEE 754
использованная литература
- ^ a b «Операторы присваивания» . cppreference.com . Справочник по C ++ . Проверено 1 марта 2021 года .
- ^ Страуструп, Бьярне (2013). Язык программирования C ++ (Четвертое изд.). Эддисон-Уэсли. ISBN 978-0-321-56384-2.
- ^ "ISO / IEC 9899: проект комитета 201x от 12 апреля 2011 г. N1570" .
- ^ «Присваивание и составные операторы присваивания» .
- ^ «Спецификация языка C #» . Microsoft . Проверено 17 марта 2014 года .