返回介绍

E.1 按位运算符

发布于 2024-10-08 23:14:16 字数 7835 浏览 0 评论 0 收藏 0

按位运算符对整数值的位进行操作。例如,左移运算符将位向左移,按位非运算符将所有的 1 变成 0,所有的 0 变成 1,C++共有 6 个这样的运算符:<<、>>、~、&、|和^。

E.1.1 移位运算符

左移运算符的语法如下:

其中,value 是要被操作的整数值,shift 是要移动的位数。例如,下面的代码将值 13 的所有位都向左移 3 位:

腾出的位置用 0 填充,超出边界的位被丢弃(参见图 E.1)。

由于每个位都表示右边一位的 2 倍(参见附录 A),所以左移一位相当于乘以 2。同样,左移 2 位相当于乘以 22,左移 n 位相当于乘以 2n。因此,13<<3 的值为 13 × 23,即 104。

图 E.1 左移运算符

左移运算符提供了通常可以在汇编语言中找到的功能。不过,左移运算符在汇编语言中会直接修改寄存器的内容,而 C++左移运算符生成一个新值,而不修改原来的值。例如,请看下面的代码:

上述代码不会修改 x 的值。表达式 x<<3 使用 x 的值来生成一个新值,就像 x+3 会生成一个新值,而不会修改 x 一样。

如果要用左移运算符来修改变量的值,则还必须使用赋值运算符。可以使用常规的赋值运算符或<<=运算符(该运算符将移动与赋值结合在一起):

正如所期望的,右移运算符(>>)将位向右移,其语法如下:

其中,value 是要移动的整数值,shift 是要移动的位数。例如,下面的代码将值 17 中所有的位向右移两位:

对于无符号整数,腾出的位置用 0 填充,超过边界的位被删除。对于有符号整数,腾出的位置可能用 0 填充,也可能用原来最左边的位填充,这取决于 C++实现(图 E.2 是一个用 0 填充的例子)。

图 E.2 右移运算符

向右移动一位相当于除以 2。向右移动 n 位相当于除以 2n

C++还定义了一个“右移并赋值”运算符,如果要用移动后的值替换变量的值,可以这样做:

在有些系统上,使用左移运算符(右移运算符)实现将整数乘(除)以 2 的速度比使用乘(除)法运算符更快,但由于编译器在优化代码方面越来越好,因此这种差异正在减小。

E.1.2 逻辑按位运算符

逻辑按位运算符类似于常规的逻辑运算符,只是它们用于值的每一位,而不是整个值。例如,请看常规的非运算符(!)和位非(或求反)运算符(~)。!运算符将 true(或非零值)转换为 false,将 false 值转换为 true。~运算符将每一位转换为它的反面(1 转换为 0,0 转换为 1)。例如,对于 unsigned char 值 3:

表达式!x 的值为 0。要知道~x 的值,先把它写成二进制形式:00000011。然后将每个 0 转换为 1,将每个 1 转换为 0。这样将得到值 11111100,在十进制中,为 252(图 E.3 是一个 16 位的例子)。新值是原值的补值。

按位运算符 OR(|)对两个整数值进行操作,生成一个新的整数值。如果被操作的两个值的对应位至少有一个为 1,则新值中相应位为 1,否则为 0(参见图 E.4)。

图 E.3 按位非运算符

图 E.4 按位运算符 OR

表 E.1 对∣运算符的操作方式进行了总结。

表 E.1 b1|b2 的值

位 值

b1 = 0

b1 = 1

b2 = 0

0

1

b2 = 1

1

1

运算符| =组合了按位运算符 OR 与赋值运算符的功能:

按位运算符 XOR(^)将两个整数值结合起来,生成一个新的整数值。如果原始值中对应的位有一个(而不是两个)为 1,则新值中相应位为 1;如果对应的位都为 0 或 1,则新值中相应位为 0(参见图 E.5)。

图 E.5 按位运算符 XOR

表 E.2 总结了^运算符的结合方式。

表 E.2 b1^b2 的值

位 值

b1 = 0

b1 = 1

b2 = 0

0

1

b2 = 1

1

0

^ =运算符结合了按位运算符 XOR 和赋值运算符的功能:

按位运算符 AND(&)将两个整数结合起来,生成一个新的整数值。如果原始值中对应位都为 1,则新值中相应位为 1,否则为 0(参见图 E.6)。

图 E.6 按位运算符 AND

表 E.3 总结了&运算符是如何运算的。

表 E.3 b1&b2 的值

位 值

b1 = 0

b2 = 1

b2 = 0

0

0

b2 = 1

0

1

& =运算符结合了按位运算符 AND 和赋值运算符的功能:

E.1.3 按位运算符的替代表示

对于几种按位运算符,C++提供了替代表示,如表 E.4 所示。它们适用于字符集中不包含传统按位运算符的区域。

表 E.4 按位运算符的替代表示

标 准 表 示

替 代 表 示

&

bitand

& =

and_eq

bitor

|=

or_eq

compl

^

xor

^ =

xor_eq

这些替代表示让您能够编写下面这样的语句:

E.1.4 几种常用的按位运算符技术

控制硬件时,常涉及打开/关闭特定的位或查看它们的状态。按位运算符提供了执行这种操作的途径。下面简要地介绍一下这些方法。

在下面的示例中,lottabits 表示一个值,bit 表示特定位的值。位从右到左进行编号,从 0 开始,因此,第 n 位的值为 2n。例如,只有第 3 位为 1 的整数的值为 23(8)。一般来说,正如附录 A 介绍的,各个位都对应于 2 的幂。因此我们使用术语位(bit)表示 2 的幂;这对应于特定位为 1,其他所有位都为 0 的情况。

1.打开位

下面两项操作打开 lottabits 中对应于 bit 表示的位:

它们都将对应的位设置为 1,而不管这一位以前的值是多少。这是因为对 1 和 1 或者 0 和 1 执行 OR 操作时,都将得到 1。lottabits 中其他所有位都保持不变,这是因为对 0 和 0 做 OR 操作将得到 0,对 1 和 0 做 OR 操作将生成 1。

2.切换位

下面两项操作切换 lottabits 中对应于 bit 表示的位。也就是说,如果位是关闭的,则将被打开;如果位是打开的,将被关闭:

对 0 和 1 执行 XOR 操作的结果为 1,因此将关闭已打开的位;对 1 和 1 执行 XOR 操作的结果为 0,因此将打开已关闭的位。lottabits 中其他所有位都保持不变,这是因为对 0 和 0 执行 XOR 操作的结果为 0,对 1 和 0 执行 XOR 操作的结果为 1。

3.关闭位

下面的操作将关闭 lottabits 中对应于 bit 表示的位:

该语句关闭相应的位,而不管它以前的状态如何。首先,运算符~bit 将原来为 1 的位设置为 0,原来为 0 的位设置为 1。对 0 和任意值执行 AND 操作都将得到 0,因此关闭相应的位。lottabits 中其他所有位都保持不变,这是因为对 1 和任意值执行 AND 操作时,该位的值将保持不变。

下面是一种更简洁的方法:

4.测试位的值

如果要确定 lottabits 中对应于 bit 的位是否为 1,则下面的测试不一定管用:

这是因为即使 lottabits 中对应的位为 1,而其他位也可能为 1。仅当对应的位为 1,而其他位皆为 0 时,上述等式才为 true。因此修补的方式是,首先对 lottabits 和 bit 执行 AND 操作,这样生成的值的对应位保持不变,因为对 1 和任何值执行 AND 操作都将保持该值不变;而其他位都为 0,因为对 0 和任何值执行 AND 操作的结果都为 0。正确的测试如下:

实际应用中,程序员常将上述测试简化为:

因为 bit 中有一位为 1,而其他位都为 0,因此 lottabits & bit 的结果要么为 0(测试结果为 false),要么为 bit(非零值,测试结果为 true)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文