Операции модификации

Модификация, называемая также составным присваиванием, позволяет объединить в одном операторе арифметические или побитовые операции с обычным присваиванием.

П

Символы

Описание

Пример

А

14

+=

Сложение с присваиванием

e1 += e2

R

14

-=

Вычитание с присваиванием

e1 -= e2

R

14

*=

Умножение с присваиванием

e1 *= e2

R

14

/=

Деление с присваиванием

e1 /= e2

R

14

%=

Деление по модулю с присваиванием

e1 %= e2

R

14

<<=

Сдвиг влево с присваиванием

e1 <<= e2

R

14

>>=

Сдвиг вправо с присваиванием

e1 >>= e2

R

14

&=

Побитовое И с присваиванием

e1 &= e2

R

14

|=

Побитовое ИЛИ с присваиванием

e1 |= e2

R

14

^=

Побитовое ИИЛИ с присваиванием

e1 ^= e2

R

Данные операторы выполняют соответствующее действие для операндов e1 и e2, после чего результат сохраняется в e1.

Выражение вида e1 @= e2, где @ — любой оператор из таблицы, примерно эквивалентно e1 = e1 @ e2. Слово "примерно" подчеркивает наличие нюансов.

Во-первых, если на месте e2 стоит выражение с оператором, у которого более низкий приоритет, чем у @, e2 все равно вычисляется раньше. То есть, если обозначить приоритет скобками, получим e1 = e1 @ (e2).

Во-вторых, если в выражении e1 присутствуют побочные модификации переменных, они производятся лишь единожды. Это демонстрирует следующий пример.

int a[] = {12345};
int b[] = {12345};
int i = 0j = 0;
a[++i] *= i + 1;           // a = {1, 4, 3, 4, 5}, i = 1
                           // не эквивалентно!
b[++j] = b[++j] * (j + 1); // b = {1, 2, 4, 4, 5}, j = 2

Здесь массивы a и b содержат одинаковые элементы и обрабатываются с помощью индексных переменных i и j. Причем выражение для массива a использует операцию '*=', а выражение для массива b — "эквивалент". Результаты не равны: отличаются как индексные переменные, так и массивы.

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

ushort x = 0;
x |= 1 << 10;

Здесь производится сдвиг 1 ('0000 0000 0000 0001') на 10 битов влево, в результате чего получается число с одним взведенным 10-м битом ('0000 0100 0000 0000'). Операция побитового ИЛИ копирует этот бит в переменную x.

Для сброса того же бита напишем:

x &= ~(1 << 10);

Здесь к 1, сдвинутой на 10 битов влево (которую мы видели в предыдущем выражении), применяется операция инверсии, в результате чего все биты меняют свое значение: '1111 1011 1111 1111'. Операция побитового И сбрасывает обнуленные биты (в данном случае один) в переменной x, все остальные биты в x остаются без изменений.