位运算符和移位运算符包括一元位补、二进制左移和右移、无符号右移、二进制逻辑 AND、OR 和异或运算符。 这些操作数采用整型数值类型或字符型操作数。
- 一元 (按位求补)运算符
- 二进制 (左移)、(右移)和 (无符号右移)运算符
- 二进制 (逻辑 AND)、(逻辑 OR)和 (逻辑异或)运算符
这些运算符是针对 、、 和 类型定义的。 如果两个操作数都是其他整数类型(、、、 或 ),它们的值将转换为 类型,这也是一个运算的结果类型。 如果操作数是不同的整数类型,它们的值将转换为最接近的包含整数类型。 有关详细信息,请参阅 C# 语言规范的数值提升部分。 复合运算符(如 )不会将其参数转换为 ,也不会具有结果类型 。
、 和 运算符也是为 类型的操作数定义的。 有关详细信息,请参阅布尔逻辑运算符。
位运算和移位运算永远不会导致溢出,并且不会在已检查和未检查的上下文中产生相同的结果。
运算符通过反转每个位产生其操作数的按位求补:
也可以使用 符号来声明终结器。 有关详细信息,请参阅终结器。
运算符将其左侧操作数向左移动右侧操作数定义的位数。 有关右侧操作数如何定义移位计数的信息,请参阅移位运算符的移位计数部分。
左移运算会放弃超出结果类型范围的高阶位,并将低阶空位位置设置为零,如以下示例所示:
由于移位运算符仅针对 、、 和 类型定义,因此运算的结果始终包含至少 32 位。 如果左侧操作数是其他整数类型(、、、 或 ),则其值将转换为 类型,如以下示例所示:
运算符将其左侧操作数向右移动右侧操作数定义的位数。 有关右侧操作数如何定义移位计数的信息,请参阅移位运算符的移位计数部分。
右移位运算会放弃低阶位,如以下示例所示:
高顺序空位位置是根据左侧操作数类型设置的,如下所示:
- 如果左侧操作数的类型是 或 ,则右移运算符将执行 算术移位:左侧操作数的最高有效位(符号位)的值将传播到高顺序空位位置。 也就是说,如果左侧操作数为非负,高顺序空位位置设置为零,如果为负,则将该位置设置为 1。
- 如果左侧操作数的类型是 或 ,则右移运算符执行逻辑移位:高顺序空位位置始终设置为零。
在 C# 11 及更高版本中可用, 运算符将其左侧操作数向右移动其右侧操作数定义的位数。 有关右侧操作数如何定义移位计数的信息,请参阅移位运算符的移位计数部分。
运算符始终执行逻辑移位。 也就是说,无论左侧操作数的类型如何,高顺序空位位置始终设置为零。 如果左侧操作数是带符号类型, 运算符将执行算术移位(即,最高有效位的值传播到高顺序空位位置)。 以下示例演示了对于负左操作数, 和 运算符之间的差别:
运算符计算其整型操作数的位逻辑 AND:
对于 操作数, 运算符对其操作数执行逻辑 AND 运算。 一元 运算符是 address-of 运算符。
运算符计算其整型操作数的位逻辑异或,也称为位逻辑 XOR:
对于 操作数, 运算符对其操作数执行逻辑异或运算。
运算符计算其整型操作数的位逻辑 OR:
对于 操作数, 运算符对其操作数执行逻辑 OR 运算。
对于二元运算符 ,窗体的复合赋值表达式
等效于
不同的是 只计算一次。
以下示例演示了使用位运算符和移位运算符的复合赋值的用法:
由于数值提升, 运算的结果可能不会隐式转换为 的 类型。 在这种情况下,如果 是预定义的运算符并且运算的结果可以显式转换为 的类型 ,则形式为 的复合赋值表达式等效于 ,但 仅计算一次。 以下示例演示了该行为:
以下列表按位运算符和移位运算符从最高优先级到最低优先级排序:
- 按位求补运算符
- 移位运算符 、 和
- 逻辑与运算符
- 逻辑异或运算符
- 逻辑或运算符
使用括号 可以更改运算符优先级决定的计算顺序:
要了解按优先级排序的完整 C# 运算符列表,请参阅 C# 运算符一文中的运算符优先级部分。
对于 、 和 表达式,实际移位计数取决于 的类型,如下所示:
- 如果 的类型为 或 ,则移位计数由右侧操作数的低阶五位定义。 也就是说,移位计数通过 (或 )计算得出。
- 如果 的类型为 或 ,则移位计数由右侧操作数的低阶六位定义。 也就是说,移位计数通过 (或 )计算得出。
以下示例演示了该行为:
所有枚举类型还支持 、、 和 运算符。 对于相同枚举类型的操作数,对底层整数类型的相应值执行逻辑运算。 例如,对于具有底层类型 的枚举类型 的任何 和 , 表达式生成与 表达式相同的结果。
通常使用具有枚举类型的位逻辑运算符,该枚举类型使用 Flags 特性定义。 有关详细信息,请参阅枚举类型一文的作为位标记的枚举类型部分。
用户定义的类型可以重载、、、、、 和 运算符。 重载二元运算符时,对应的复合赋值运算符也会隐式重载。 用户定义类型不能显式重载复合赋值运算符。
如果用户定义类型 重载了 、 或 运算符,则左侧操作数的类型必须为 。 在 C# 10 及更早版本中,右侧操作数的类型必须为 ;从 C# 11 开始,重载移位运算符的右侧操作数的类型可以是任意类型。
有关更多信息,请参阅 C# 语言规范的以下部分:
- 按位求补运算符
- 移位运算符
- 逻辑运算符
- 复合赋值
- 数值提升
- C# 11 - 宽松的移位要求
- C# 11 - 逻辑右移运算符
- C# 运算符和表达式
- Boolean 逻辑运算符
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/13790.html