Дополненное задание
Эта статья нуждается в дополнительных цитатах для проверки . ( сентябрь 2014 г. ) |
Расширенное присваивание (или составное присваивание ) — это имя, данное определенным
присваивания операторы в некоторых языках программирования (особенно в тех, которые произошли от 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 — длинное имя, потребуется меньше ввода. Последнее было основой аналогичной функции в компиляторах АЛГОЛА , предлагаемых в системах Burroughs B6700 , где символ тильды использовался для обозначения присваиваемой переменной, так что
LongName:=x + sqrt(LongName)*7;
стал бы
LongName:=x + sqrt(~)*7;
и так далее. Это более общее, чем просто x:=~ + 1;
Создание оптимального кода останется прерогативой компилятора.
Семантика
[ редактировать ]В языках программирования, ориентированных на выражения, таких как C, присваивание и расширенное присваивание представляют собой выражения, имеющие значение. Это позволяет использовать их в сложных выражениях. Однако это может привести к появлению последовательностей символов, которые трудно прочитать или понять, и, что еще хуже, опечатка может легко привести к другой последовательности тарабарщины, которая, хотя и принимается компилятором, не дает желаемых результатов. В других языках, таких как Python, присваивание и расширенное присваивание являются операторами, а не выражениями, и поэтому не могут использоваться в сложных выражениях. Например, следующее допустимо для C, но недопустимо для Python:
a += b += c
Как и присваивание, в этих языках расширенное присваивание является формой правоассоциативного присваивания .
В отличие от C, составные выражения присваивания в C++ возвращают значение lvalue . [1] Будучи lvalue, его можно записать в левой части какого-либо другого оператора присваивания: [2]
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] [3] [4] [5]
Поддерживаемые языки
[ редактировать ]В следующем списке, хотя и не является полным и всеобъемлющим, перечислены некоторые основные языки программирования, поддерживающие расширенные операторы присваивания.
|
См. также
[ редактировать ]- Составной оператор
- Слитая операция
- Операторы увеличения и уменьшения — частный случай расширенного присваивания на 1.
- Расширенная арифметическая операция IEEE 754
Ссылки
[ редактировать ]- ^ Jump up to: а б «Операторы присваивания» . cppreference.com . Справочник по С++ . Проверено 1 марта 2021 г.
- ^ Страуструп, Бьярне (2013). Язык программирования C ++ (Четвертое изд.). Аддисон-Уэсли. ISBN 978-0-321-56384-2 .
- ^ «Проект комитета ISO/IEC 9899:201x, N1570, 12 апреля 2011 г.» .
- ^ «Операторы присваивания и составные операторы присваивания» .
- ^ «Спецификация языка C#» . Майкрософт . Проверено 17 марта 2014 г.