qtのopenGLに関するチュートリアルを読んでいました。マウスイベントスロットの1つには、次のコードが含まれています。
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
&演算子はifステートメントで何をしますか?==とまったく同じですか?
qtのopenGLに関するチュートリアルを読んでいました。マウスイベントスロットの1つには、次のコードが含まれています。
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
&演算子はifステートメントで何をしますか?==とまったく同じですか?
と同じではありません==
。これはビット単位のAND演算子です。この式は、から戻り値を受け取り、それを。で表される値event->buttons()
とビット単位でANDQt::LeftButton
します。結果の値がゼロ以外の場合、ブロックが実行されています。
本質的には、で指定されたボタンが押されているかどうかをチェックしますQt::LeftButton
。
ここで演算子が使用される理由は、ビットマスクbitwise AND
と呼ばれるものです。つまり、の戻り値は、ビットがさまざまな種類の状態を表す値にすぎないということです。ここで&演算子を使用すると、によって返される値に特定のビット(で示される)がset(1)またはunset(0)されているかどうかがチェックされます。テストされたビットが設定されていない場合、戻り値はゼロであり、テストされたビットの少なくとも1つが設定されている場合、戻り値はゼロではありません。event->buttons()
Qt::LeftButton
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)
基本的に、ビット値の2つの値が一致します。
(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言語のブール値はfalseの場合は0です。ゼロ以外のものはすべて真です。
これにより、1番目と2番目のビットが番号3で使用可能であることが証明されました。ただし、1と2には一致するビットがありません。
ビット演算子を調べます。より良い理解を得るために。
event->buttons()
おそらく、各ビットが1つのボタンを表すビットの組み合わせである値を返します。Qt::LeftButton
おそらく「左ボタン」に対応する位置に1ビットだけが設定された値になります。ここでビット単位のAND(&)を使用すると、これら2つの値の個々のビットがANDされ、結果がゼロ以外の場合、条件は真と見なされます。
にはビットが1つQt::LeftButton
しかないため、ゼロ以外の値を取得する唯一の方法event->buttons()
は、同じビットが設定されている場合です。(他のビットも設定されている場合がありますが、の位置にあるゼロビットとAND演算すると、それらはなくなります。事実上、式は「で表されるビットが含まれているQt::LeftButton
場合にのみtrue」を意味します。event->buttons()
Qt::LeftButton
これはビット単位のAND演算子です。
0011
& 0101
------
0001
これはビットごとのAND演算子です。より良い質問は次のとおりです。ここでのAND演算子の仕事は何ですか?なぜここでそのような「低レベル」の方法を使用するのですか?
ここに一連のフラグがあります。押したままのボタンのセットは、で表されevent->buttons()
ます。つまり、押したままのすべてのボタンの合計です。ただし、すべてのボタンは2の一意の累乗であるため、押したままのすべてのボタンの合計は整数のビットのセットになります。これは、C / C ++で制限された要素の単純なセットを表現する方法の重要な部分であるため、これを理解していただければ幸いです。
重要なのは、いわゆるビットセットのすべてのビットがセットの1つの要素を表すということです。したがって、すべての要素には一意の番号があり、ビットセットに対してテストできる必要があります(ビットセットに含まれている場合)。
イベント中に左ボタンが押されたかどうかをテストする場合は、ビットセットにビットが設定されているかどうかを確認する必要があります。これは、ビット単位のAND演算子を使用して行われます。これは、ブールAND演算を使用して、オペランドのすべてのビットをビットごとに結合するためです。ご存知のとおり、AND演算は、両方の入力ビットがtrueの場合にのみtrueを返します。したがって、ビット単位のAND演算は、入力ビットのマスクとして機能します。右のオペランドは、右のオペランドに存在する左のオペランドのビットを「フィルターで除去」します。
if
値がゼロに等しくない場合にのみ条件が真と解釈されるため、これは、右のオペランドのビットが左のオペランドにも表示されるかどうかという問題に等しくなります。この具体的なシナリオでは、これは次のことを意味します。値は値にQt::LeftButton
ビット単位で含まれていますevent->buttons()
か、または:によって表されるビットは、によって表されるビットQt::LeftButton
セットに含まれていevent->button()
ますか?
または単に:左ボタンが押されていますか?