【问题标题】:What does this & operator mean here?这个 & 运算符在这里是什么意思?
【发布时间】:2012-06-22 21:51:57
【问题描述】:

我正在阅读一些关于 qt 中 openGL 的教程。 其中一个鼠标事件槽中包含以下代码:

if (event->buttons() & Qt::LeftButton) {    
    rotationX += 180 * dy;
    rotationY += 180 * dx;
    updateGL();
}

& 运算符在 if 语句中的作用是什么? 和 == 完全一样吗?

【问题讨论】:

    标签: c++ bitwise-operators


    【解决方案1】:

    它与== 不同。它是 按位与 运算符。该表达式的作用是从event->buttons() 获取返回值,然后将其与Qt::LeftButton 表示的值进行位与。如果结果值非零,则正在执行该块。

    本质上,它检查Qt::LeftButton指定的按钮是否被按住。

    这里使用bitwise AND 运算符的原因是一种称为位掩码的东西。这意味着event->buttons() 的返回值只是一个值,它的位代表不同类型的状态。这里 & 运算符的作用是检查 event->buttons() 返回的值中的某些位(由 Qt::LeftButton 表示)是否被设置(1)或取消设置(0)。如果没有设置测试位,则返回值为零,如果设置了至少一个测试位,则返回非零。

    更多关于按位运算如何工作的细节可以在这里找到:Wikipedia article about Bitwise operations

    【讨论】:

    • 作为与 == 不同的实际示例,我想还有 Qt::RightButton、Qt::MiddleButton 等。它们都有不同的按位组合值。 Qt::AnyMouseButton 可能等于 Qt::RightButton | Qt::左按钮 | Qt::MiddleButton。您可以执行位掩码操作以查看是否设置了这些组合。或者在原始问题的示例中,如果有多个按钮与事件相关联,您可以检查 LeftButton 是否按下,即使该事件还表明 RightButton 也被按下。
    • 非常感谢!这是非常有用的!因此,如果我在这里使用 == 而不是 & ,它会做与 & 相同的工作还是只返回 false ,因为按位它们不一样?抱歉没关系我明白了~
    【解决方案2】:

    这将测试值 event=>buttons() 具有 Qt::LeftButton 位。

    如果没有那个位,结果将是 0。和一个 Qt::LeftButton 如果它确实包含那个位。

    这是一种比较,检查数字上是否存在标志或位值

    0001 == 1
    0010 == 2
    0011 == 3
    
    1 & 2 == 0 (false)
    1 & 3 == 1 (true)
    2 & 3 == 2 (true)
    

    本质上,这两个值的位值是匹配的。

      (0001) 
    & (0010)
    ---------
      (0000) //Neither have the same bit
    
      (0011)
    & (0010)
    ---------
      (0010) //both have bit 2
    
      (0101)
    & (0110)
    ---------
      (0100) // Both have the 3rd bit
    
      (0111)
    & (0110)
    ---------
      (0110) // Both have the 2nd and 3rd bit
    

    C 语言中的布尔值是 0 表示 false。任何非零都是真的。

    这证明了第 1 位和第 2 位在数字 3 中可用。但是 1 和 2 没有匹配的位。

    查看位运算符。以便更好地理解。

    http://en.wikipedia.org/wiki/Bitwise_operation

    【讨论】:

      【解决方案3】:

      这是按位与运算符。

        0011
      & 0101
      ------
        0001
      

      【讨论】:

        【解决方案4】:

        event->buttons() 可能返回一个值,该值是位的组合,其中每个位代表一个按钮。 Qt::LeftButton 将是一个值,可能在对应于“左键”的位置上只设置了一个位。在这里使用按位与 (&) 对这两个值的各个位进行与,如果结果非零,则条件将被视为真。

        由于Qt::LeftButton 中只有一位,因此获得非零值的唯一方法是event->buttons() 设置了相同的位。 (它也可能设置了其他位,但是当它们与Qt::LeftButton 中这些位置的零位进行与运算时,这些位就会消失。那么,有效地,表达式意味着“当且仅当event->buttons() 包含表示的位时为真由Qt::LeftButton"。

        【讨论】:

          【解决方案5】:

          这是按位与运算符。更好的问题是:AND 运算符的工作 是什么?为什么我们在这里使用这种“低级”的方法?

          我们在这里有一组标志。按住的按钮集由event->buttons() 表示。这意味着,它是所有按下的按钮的总和。但是每个按钮都是唯一的 2 次幂,因此所有按下的按钮的总和是整数中的一组位。我希望你能理解这一点,因为这是我们如何在 C/C++ 中表示简单的有限元素集的重要部分。

          重点是,所谓的bitset中的每一位都代表了集合中的一个元素。每个元素都有一个唯一的编号,我们必须能够针对 bitset 进行测试(如果它包含在 bitset 中)。

          如果要测试事件期间是否按住了左键,则必须检查 bitset 中是否设置了该位。这是使用按位 AND 运算符完成的,因为它使用布尔 AND 运算逐位组合了操作数的所有位。正如您应该知道的,当且仅当两个输入位都为真时,AND 运算才返回真。所以 bitwise AND 操作作为输入位的掩码。右操作数“过滤掉”右操作数中存在的左操作数位。

          当且仅当值不等于 0 时,if 条件才被解释为真,这就等于是右操作数的位是否也出现在左操作数中的问题。在这个具体场景中,这意味着:值Qt::LeftButton是否按位包含在值event->buttons()中,或者:Qt::LeftButton表示的位是否包含在event->button()表示的位集中?

          或者简单地说:左键是否被按住?

          【讨论】:

            猜你喜欢
            • 2010-12-30
            • 2016-03-07
            • 2021-12-18
            • 2021-04-02
            • 1970-01-01
            • 2013-07-03
            • 2013-07-30
            • 1970-01-01
            相关资源
            最近更新 更多