修改运算

“修改”也称为复合赋值,允许在单个运算符内实现 算术按位 运算与常规 赋值的结合。

优先级

符号

说明

示例

结合性

14

+=

赋值加法

e1 += e2

14

-=

赋值减法

e1 -= e2

14

*=

赋值乘法

e1 *= e2

14

/=

赋值除法

e1 /= e2

14

%=

赋值模除法

e1 %= e2

14

<<=

赋值左移

e1 <<= e2

14

>>=

赋值右移

e1 >>= e2

14

&=

赋值按位“与”

e1 &= e2

14

|=

赋值按位“或”

e1 |= e2

14

^=

赋值按位“与/或”

e1 ^= e2

这些运算符对 e1e2 操作数执行相关操作,运算结果存储在 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
                           // not equivalent!
b[++j] = b[++j] * (j + 1); // b = {1, 2, 4, 4, 5}, j = 2

此处,ab 数组包含相同的元素,并使用索引变量 ij 进行处理。同时,a 数组的表达式使用了 *= 运算,而 b 数组的表达式使用了等效运算。结果并不相等:索引变量和数组都不同。

其他运算符在处理位级操作的问题时会很有用。因此,以下表达式可用于将特定位设置为 1:

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

此处,将 1 ('0000 0000 0000 0001') 左移 10 位,获得一个第 10 位为 1 的数字 ('0000 0100 0000 0000')。按位“或”运算将该位拷贝到变量 x

要重置相同的位,可以编写:

x &= ~(1 << 10);

这里,对左移 10 位的 1(我们在上述表达式中看到了结果)进行取反运算,这导致所有位的值都发生变化:'1111 1011 1111 1111'。按位“与”运算可重置 x 变量中的零位(在本例中为 1),而 x 中的所有其他位保持不变。