我正在阅读一些关于 qt 中 openGL 的教程。其中一个鼠标事件槽中包含以下代码:
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
if 语句中 & 运算符的作用是什么?它与 == 完全相同吗?
我正在阅读一些关于 qt 中 openGL 的教程。其中一个鼠标事件槽中包含以下代码:
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
if 语句中 & 运算符的作用是什么?它与 == 完全相同吗?
它不一样==
。它是按位与运算符。该表达式的作用是它从 中获取返回值event->buttons()
并按位与它与由 表示的值相乘Qt::LeftButton
。如果结果值非零,则正在执行块。
本质上,它检查 指定的按钮Qt::LeftButton
是否被按住。
bitwise AND
此处使用运算符的原因是一种称为位掩码的东西。这意味着返回值event->buttons()
只是一个值,它的位代表不同类型的状态。& 运算符在这里所做的是检查某些位(由 表示Qt::LeftButton
)是否在返回的值中被设置(1)或未设置(0)event->buttons()
。如果没有设置测试位,则返回值为零,如果设置了至少一个测试位,则返回值非零。
可以在此处找到有关按位运算如何工作的更多详细信息:有关按位运算的维基百科文章
这将测试值 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 表示假。任何非零都是真的。
这证明了数字 3 中的第 1 位和第 2 位可用。但是 1 和 2 没有匹配的位。
查看按位运算符。以获得更好的理解。
这是按位与运算符。更好的问题是:AND 运算符在这里的工作是什么?为什么我们在这里使用这种“低级”的方法?
我们在这里有一组标志。按住的按钮集由 表示event->buttons()
。这意味着,它是所有按下的按钮的总和。但是每个按钮都是唯一的 2 次幂,因此所有按下的按钮的总和是整数中的一组位。我希望你能理解这一点,因为这是我们如何在 C/C++ 中表示简单的有限元素集的重要部分。
关键是,所谓的 bitset 中的每一位都代表集合中的一个元素。每个元素都有一个唯一的编号,我们必须能够针对 bitset 进行测试(如果它包含在 bitset 中)。
如果要测试在事件期间是否按住了左键,则必须检查 bitset 中是否设置了该位。这是使用按位 AND 运算符完成的,因为它使用布尔 AND 运算逐位组合了操作数的所有位。正如您应该知道的,当且仅当两个输入位都为真时,AND 运算才返回真。因此,按位与运算用作输入位的掩码。右操作数“过滤掉”右操作数中存在的左操作数位。
由于if
当且仅当值不等于 0 时,条件才被解释为真,这等于右操作数的位是否也出现在左操作数中的问题。在这个具体场景中,这意味着:值是否Qt::LeftButton
按位包含在值中event->buttons()
,或者:由 表示的位是否Qt::LeftButton
包含在由表示的位集中event->button()
?
或者简单地说:左键是否被按住?
这是按位与运算符。
0011
& 0101
------
0001
event->buttons()
大概返回一个值,该值是位的组合,其中每个位代表一个按钮。Qt::LeftButton
将是一个值,可能在对应于“左键”的位置上只设置了一个位。在这里使用按位与 (&) 对这两个值的各个位进行与,如果结果非零,则条件将被视为真。
由于 中只有一位Qt::LeftButton
,因此获得非零值的唯一方法是event->buttons()
设置相同的位。(它也可能设置了其他位,但是当它们与 中的那些位置的零位进行与运算时,这些位就会消失Qt::LeftButton
。那么,有效地,表达式的意思是“当且仅当event->buttons()
包含由Qt::LeftButton
”表示的位时才为真。