1

私は C/C++ の専門家ではありません。

今日、次の宣言を見つけました。

typedef NS_OPTIONS(NSUInteger, PKRevealControllerType)
{
    PKRevealControllerTypeNone  = 0,
    PKRevealControllerTypeLeft  = 1 << 0,
    PKRevealControllerTypeRight = 1 << 1,
    PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight)
};

すべての値が持つ値を翻訳できますか?

4

4 に答える 4

6

operator<<ビットごとの左シフト演算子です。指定された回数だけすべてのビットを左にシフトします: (算術左シフトおよび予約符号ビット)

m << n

toのすべてのビットを何度もm左にシフトしますn。( 1 つのシフト == 2 倍することに注意してください)。

1 << 0シフトがないことを意味するので、それは only に等しいです1

1 << 11シフトを意味するため、1*2= 2 のみに等しくなります。

1 バイトで説明します。1 バイトに 1 つは次のようなものです。

 MSB
+----+----+----+---+---+---+---+---+
|  0 |  0 | 0  | 0 | 0 | 0 | 0 | 1 |       1   
+----+----+----+---+---+---+---+---+
  7     6   5    4   3   2   1 / 0  
  |                           /           1 << 1
  |                          | 
  ▼                          ▼
+----+----+----+---+---+---+---+---+
|  0 |  0 | 0  | 0 | 0 | 0 | 1 | 0 |       2      
+----+----+----+---+---+---+---+---+ 
   7    6   5    4   3   2   1   0

一方1 << 0、図1のように何もしません。(符号を保持するために 7 番目のビットがコピーされることに注意してください)

OR 演算子: ビットごとに or を実行

 MSB                            PKRevealControllerTypeLeft
+----+----+----+---+---+---+---+---+
|  0 |  0 | 0  | 0 | 0 | 0 | 0 | 1 |  == 1
+----+----+----+---+---+---+---+---+
   7    6   5    4   3   2   1   0
   |    |    |   |   |   |   |   |      OR
 MSB                               PKRevealControllerTypeRight
+----+----+----+---+---+---+---+---+
|  0 |  0 | 0  | 0 | 0 | 0 | 1 | 0 |   == 2
+----+----+----+---+---+---+---+---+
   7    6   5    4   3   2   1   0

 = 

 MSB                    PKRevealControllerTypeBoth
+----+----+----+---+---+---+---+---+
|  0 |  0 | 0  | 0 | 0 | 0 | 1 | 1 |   == 3
+----+----+----+---+---+---+---+---+
   7    6   5    4   3   2   1   0  

|ビット単位の演算子です。以下のコードではor 1 | 2==3

PKRevealControllerTypeNone  = 0,             //  is Zero
PKRevealControllerTypeLeft  = 1 << 0,        //  one 
PKRevealControllerTypeRight = 1 << 1,        //  two
PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft |    
                             PKRevealControllerTypeRight)  // three

このような初期化された値には、これ以上技術的な理由はありません。そのように定義すると、物事がうまく整列します。この回答を読んでください: define SOMETHING (1 << 0)

コンパイラの最適化のようにそれらをより簡単に変換します:( 3番目のものについてはわかりませんが、コンパイラもそれを最適化すると思います)

PKRevealControllerTypeNone  = 0,     //  is Zero
PKRevealControllerTypeLeft  = 1,     //  one 
PKRevealControllerTypeRight = 2,     //  two
PKRevealControllerTypeBoth  = 3,     // Three

編集: @Till に感謝します。この回答を読むBOOL フラグを使用したアプリの状態は、ビットごとの演算子を使用して取得した宣言の有用性を示しています。

于 2013-03-29T17:45:54.887 に答える
3

これはビット フラグの列挙型です。

PKRevealControllerTypeNone  = 0       // no flags set
PKRevealControllerTypeLeft  = 1 << 0, // bit 0 set
PKRevealControllerTypeRight = 1 << 1, // bit 1 set

その後

PKRevealControllerTypeBoth = 
  (PKRevealControllerTypeLeft | PKRevealControllerTypeRight)

他の 2 つのフラグをビットごとに OR した結果です。したがって、ビット 0 とビット 1 がセットされます。

<<演算子は左シフト演算子です。また、|演算子はビットごとの OR です。

要約すると、結果の値は次のとおりです。

PKRevealControllerTypeNone  = 0
PKRevealControllerTypeLeft  = 1
PKRevealControllerTypeRight = 2
PKRevealControllerTypeBoth  = 3

しかし、ビットのフラグの観点から考えた方がはるかに理にかなっています。または、ユニバーサル セットが次のようなセットとして: {PKRevealControllerTypeLeft、PKRevealControllerTypeRight}

詳細については、列挙型、シフト演算子、およびビットごとの演算子について読む必要があります。

于 2013-03-29T17:44:51.733 に答える
2

これは C++ ではなく Objective C のように見えますが、関係ありません。

1 << 0

0 の位置だけ 1 ビット左 (上) にシフトされます。任意の整数 "<<0" はそれ自体です。

そう

1 << 0 = 1

同様に

1 << 1

1ビットだけ左に1ビットシフトされます。いくつかの方法を視覚化できますが、最も簡単なのは 2 を掛けることです。[注 1]

そう

x << 1 == x*2

また

1 << 1 == 2

最後に、単一のパイプ演算子はビットごとの orです。

そう

1 | 2 = 3

tl;dr:

PKRevealControllerTypeNone  = 0
PKRevealControllerTypeLeft  = 1
PKRevealControllerTypeRight = 2
PKRevealControllerTypeBoth  = 3

[1] この一般化にはいくつかの制限があります。たとえば、xがデータ型によって格納できる最大値の 1/2 以上の場合です。

于 2013-03-29T17:47:48.793 に答える
2

これはすべてビット演算に帰着します。

PKRevealControllerTypeNone の値は 0 (バイナリ 0000) です。

PKRevealControllerTypeLeft の値は 1 (バイナリ 0001) です。

PKRevealControllerTypeRight の値は 2 (バイナリ 0010) です。これは、0001 が左にシフトされ、1 ビットが 0010 であるためです。

PKRevealControllerTypeBoth の値は 3 (バイナリ 0011) から 0010 | 0001 (または足し算のような働き) = 0011

コンテキストでは、これは値を決定するために使用される可能性が最も高いです。プロパティ is &(またはbitwise-and) は乗算と同様に機能します。ands1に数値を指定すると、数値が保持され、0ands に数値を指定すると、数値がクリアされます。

したがって、特定のコントローラーが具体的に型Leftであり、その値0010(つまり type Right)0010 & 0001 = 0が期待どおり false であるかどうかを確認したい場合 (つまり、正しい型ではないと判断したことになります)。ただし、コントローラーがBoth 0011 & 0001 = 1そうである場合、これは型であると判断したため、結果は true ですBoth

于 2013-03-29T17:45:05.077 に答える