C++ 按位运算符

2024年8月28日 | 阅读 11 分钟

可以通过多种方式使用 位运算符 来管理。我们使用 位运算符(如 (|, &, ^, ~, <<, >>) 来处理位,以及使用 数学运算符(如 (+, -, /, *) 来处理整数,其方式是等效的。

在本文中,我们将探讨 C++ 中六种不同类别的 位运算符。在 C++ 中,我们将理解它们的内部工作原理和语法。

  • AND (&)
  • OR (|)
  • XOR (^)
  • COMPLEMENT (~)
  • Left Shift (<<)
  • Right Shift (>>)

虽然其中一些 运算符的名称符号 可能与逻辑运算符相似,但它们不能互换使用。

C++ 中的位运算符与逻辑运算符

对于初学者来说,位运算符,如 AND、ORXOR,可能会令人困惑。

如果您之前学习过 逻辑运算符,那么 逻辑 AND逻辑 OR 可能对您来说很熟悉。许多人认为它们经常与 位 AND位 OR 运算符 混淆。让我们试着找出它们之间有什么区别。逻辑运算符 使用 布尔数据,并输出 TrueFalse 布尔值

C++ 中的位运算符 在整数上操作;也就是说,它们接受整数输入,执行 位操作,然后返回 整数输出。而 逻辑 ANDOR 使用 '&&''||' 作为它们的运算符,位 ANDOR 则使用 '&''|'

C++ 中的位运算符类型

既然您已经了解了 逻辑运算符位运算符 之间的区别以及位运算符是什么,让我们更仔细地了解一下它们。

AND (&) 运算符

位 AND 运算符 使用 单个 & 符号 来表示。这个 二元运算符 需要 两个操作数,即 两个数字 才能工作。

它对 操作数的二进制值执行 位级别的逻辑 AND 运算符。也就是说,如果两个操作数在期望的位置上都有 1,则输出在该位置上也将是 1,否则为 0

C++ 中位 AND 运算符的真值表

Num1Num2Result=Num1 & Num2
000
100
010
111

示例

输出

3 & 4 = 0

工作机制

上面的代码片段执行了 34按位与 操作。让我们仔细看看它们是如何工作的。

  1. 在二进制中,4 等于 1003 等于 11
  2. 通过在最高有效位 左侧 添加 ,最短的二进制值必须首先被转换为最长二进制值的长度。
  3. 在这里,3 的长度是 2,而 4 的长度是 3,这是最大的数字。在 3 中添加 0 作为最高有效位,使它们的长度相同。
  4. 现在,3 的二进制表示为 0114 的二进制表示为 100
  5. 现在,从 对位执行逻辑 AND 操作,并将结果存储在相应的位置。
  6. 逻辑 AND0 视为 False,将 1 视为 True。因此结果将是 false,结果的第一个位将是 03 的第一个位是 04 的第一个位是 1
  7. 在二进制值过程中,重复相同的过程。由于 34 的第二位都是 0,因此结果的第二位将保存为 0
  8. 同样,由于 34 的第三位和最后一位都是 0,因此 0 将是结果的 第三个最后一位
  9. 因此,结果的最终二进制值为 000,当转换为整数十进制时,等于 0

OR 运算符

按位与按位或 运算符之间的唯一区别是 按位或 运算符在 位级别 执行逻辑 OR 而不是逻辑 AND。也就是说,如果至少一个操作数具有 1,则结果在相应位置上也将具有 1,如果它们在相应位置上都具有 0,则结果为 0竖线管道符号,即 |,用于表示此运算符。

C++ 中位 OR 运算符的真值表

Num1Num2Result=Num1 | Num2
000
101
011
111

示例

输出

3 | 4 = 7

工作机制

上面的代码片段执行了 34按位或 操作。让我们仔细看看它们是如何工作的。

  1. 以二进制形式,4 等于 1003 等于 11
  2. 通过在最高有效位 左侧 添加零,最短的二进制值必须首先被 转换最长二进制值的长度
  3. 现在,我们有 30114100
  4. 现在,从 对位执行逻辑 OR 操作,并将结果存储在相应的位置。
  5. 由于 34 的初始位分别为 01,因此结果的第一个位是 1
  6. 由于 34 的第二位都是 10,因此结果的第二位也是 1
  7. 结果的第三位是 1,因为 34 的第三位分别为 10
  8. 因此,结果的二进制值为 111,转换为十进制形式为 7。

XOR 运算符

与前两个相比,主要区别在于它们在 位级别 执行逻辑 XOR。也就是说,如果仅有一个操作数具有 1 而另一个具有 0,则结果在相应位置将具有 1。如果它们都具有相同的位,例如都为 0 或都为 1,则结果将为 0。

C++ 中位 XOR 运算符的真值表

Num1Num2Result=Num1^Num2
000
101
011
110

示例

输出

3 ^ 4 = 7

工作机制

上面的代码片段执行了 34 的按位 XOR 操作。让我们仔细看看它们是如何工作的。

  1. 以二进制形式,4 等于 1003 等于 11
  2. 我们必须首先通过在 最重要的位左侧 添加 来将最短的二进制值扩展到其完整长度。
  3. 现在,3 的二进制表示为 0114 的二进制表示为 100
  4. 现在,从 工作,逻辑上对位进行 XOR,然后将结果存储在相应的位置。
  5. 由于 34 的初始位分别为 01,因此结果的第一个位是 1
  6. 由于 34 的第二位都是 10,因此结果的第二位也是 1
  7. 结果的第三位是 1,因为 34 的第三位分别为 10
  8. 结果的二进制值为 111,转换为十进制形式时得到数字 7

在继续其他运算符之前,让我们看一下我们到目前为止已经检查过的 C++ 中三个位运算符的 真值表

XYx& yX | yX ^ y
00000
01011
10011
11110

表: C++ 中位 AND、ORXOR 操作的通用真值表。

Complement 运算符

如果您观察到了,到目前为止我们看到的三个位运算都是二元运算符,这意味着它们都需要 两个操作数 才能工作。然而,这个运算符是不同的,因为它是唯一只需要 一个操作数 的位运算符。其他位运算需要 两个运算符

按位补码 运算符返回单个值的 一的补码。数字的 一的补码 是通过将二进制值的 所有 0 转换为 1,将 所有 1 转换为 0 来创建的。它由 波浪号,即 '~' 来表示。

C++ 中位补码运算符的真值表

Num1Result = ~Num1
01
10

示例

输出

~5 = -6

工作机制

上面的代码片段执行了 5 的按位 补码操作翻转 所有位会得到 101,转换为十进制是 010,即 2

注意

  1. 在这种情况下,逻辑表明 5 = 2,但编译器输出的是输入值的 补码 2。
  2. 使用 2 的补码 来存储 负数
  3. 5 的二进制代码是 0000 0101
  4. 1111 1010 是 5 的 一的补码
  5. 6二进制代码0000 0110
  6. 数字 161111 1001
  7. 为了得到 1 的 2 的补码,在其一的补码(6 = 1111 1010)上加 1。它等于 5
  8. 因此,65 的按位补码。

到目前为止,我们已经介绍了 C++ 中的 4 种位运算符。它们都在 位级别 上执行与 逻辑运算符布尔变量 上执行的相同操作,这使得它们与逻辑运算符非常相似。然而,接下来的两个运算符彼此之间存在显著差异。

Left Shift (<<) Operator

左移运算符 将指定数量的位向 移动整数值的位模式。左移运算符 需要两个操作数:要移动的 ,例如 “x”,以及第二个值,例如 “n”,表示需要将 第一个值 移动的位数。

如果 “n” 的值为负,则会引发编译器错误 “负移位计数”“x” 的值可以是 负数,但 “n” 的值不能是负数。当 'x' 的值为 负数 时,对数字的 2 的补码 应用 左移 操作。因此,数字的符号可能与 左移操作 的符号匹配,也可能不匹配。

两个连续的大于 运算符,或 <<,用于表示 左移运算符。如果 n运算符右侧 的操作数,则相当于将整数乘以 2 的 n 次方

为什么会这样?

许多人问这是一个非常明确的问题,因为当一个数字向左移动时,它的基值会乘以 新数字。当您在十进制中将 3 的值向 移动并向其 最右侧 添加 0 时,您实际上是在乘以 10,这是它的基值。

例如,如果您将 3 移动 1 位,您将得到 30,即 3*10。任何基值都具有相同的属性。左移 运算符仅对二进制数据进行操作。因此,结果与乘以 2 的幂相同。

语法

它具有以下语法:

示例

输出

5 << 2 = 20

工作机制

  1. 上面的代码片段对 十进制值 5 应用了 左移操作
  2. 它将 52 位模式 进行修改。
  3. 5 的二进制值为 101
  4. 当您将其向 移动 两格 并向 最低有效位(位于二进制序列的 端)添加两个 0 时,结果是 10100
  5. 二进制到十进制转换 的结果是 20

Right Shift (>>) Operator

右移左移 运算符之间的主要区别在于 右移 运算符将位向 移动而不是 移动。其余的位通过弹出提供的值的最后 n 位,从二进制转换为整数。

右移 运算符遵循与 左移运算符 相同的指南。如果 “n” 的值为 负数,则会引发编译器错误 “负移位计数”“x” 的值可以是 负数,但 “n” 的值不能是负数。

使用 右移运算符负数 进行操作时,与 左移运算符 一样,使用的是数字的 2 的补码

因此,当您对 负整数 执行 右移操作 时,结果将是一个 正数,因为您将符号位替换为 0,将之前的位(即 1)移到下一个位置。两个连续的小于 符号,或 >>,用于表示此运算符。

语法

它具有以下语法:

它相当于使用 n 的 second power 将给定整数除以其地板值。

当您将数字向 移位时,就像向 移位 时一样,您实际上是在除以 基值。当您在十进制中将数字 345 移位弹出 最后一个字符时,您实际上是在除以 10,这是它的 基值

例如,如果您将 345 移动 一位,您将得到 34,即 345/10。任何基值都具有相同的属性。由于 右移 运算符使用二进制数字,因此结果与除以 2 的幂相同。

示例

输出

20 >> 2 = 5

工作机制

  1. 上面的代码片段对 十进制值 20 应用了 右移操作
  2. 20 的位模式被移动了 2
  3. 20 的二进制值为 10100
  4. 当您 弹出 最后 两位 并将它向 移动两格时,结果是 101
  5. 当结果从 二进制转换为整数 时,得到 5。

结论

在本文中,您了解了位运算符是什么,它们与 逻辑运算符 有何不同,以及它们在 C++ 中的作用。当正确使用时,位运算 可以帮助您节省大量时间。位操作技术的一些最流行的应用包括

  • 使用 OR 符号 (|)空格键 生成 小写英文字母
  • AND ('&') 一起使用时,下划线将英文转换为大写
  • 对于 英文字母的切换大小写,请使用 XOR ""空格键
  • 交换两个数字。
  • 验证提供的数字是否为 2 的幂