6

列挙型をC++コードからC#コードに変換しようとしていますが、頭を包み込むのに問題があります。C++コードは次のとおりです。

enum FOO {
  FOO_1 = 0,
  FOO_2,
  // etc
 }

#define MASK(x)  ((1 << 16) | (x))

enum DISP
{
  DISP_1 = MASK(FOO_1),
  DISP_2 = MASK(FOO_2),
  // etc
}

私が理解していないのは、MASKが何をしているのか、そしてC#で機能をエミュレートする方法、またはそれが何をしているのかを理解し、それなしで列挙型DISPを手動で設定する方法です。

私が言っていることが理にかなっているのかわかりませんが、私が何を見ているのか完全に確信が持てない場合、それは予想されることです。

4

5 に答える 5

7

ビットシフトすると、すべての1と0がいくつかの値だけ左または右にシフトします。

あなたの場合1 << 16、バイナリで10000000000000000を作成します。(はい、それは16個のゼロです)。

次に、その数を取り|、ビット単位の演算子を使用します。したがって、列挙型の整数値が何であれ、ビット単位でシフトされた数値になります。

たとえば、MASK(FOO_4)(リテラル値が3の)3は2進数で11であるため、結果は10000000000000011になります。これは、各値に65,536を加算するのと機能的に同じです。

ここで、2番目の列挙型を宣言するときに、それらの列挙型の値をこの奇妙なマスキング関数に設定しています。

C#で同じことを行うには、次のことを試してください。

enum Foo { //this may not be needed anymore?
   FOO_1 = 0, FOO_2, ... etc
}

enum Disp { //DISP_2 gets the next value ie 65536 + 1, and so forth
   DISP_1 = 65536, DISP_2, DISP_3, ... etc
于 2012-10-12T00:52:55.083 に答える
6

MASK(x)2進数の数値をOR-ingすることによって数値を作成します(1つは左に16回シフトされます)。x10000000000000000

C#では、次のように式を直接使用できます。

enum FOO {
    FOO_1 = 0,
    FOO_2,
    // etc
}

enum DISP
{
    DISP_1 = (1<<16) | (int)(FOO.FOO_1),
    DISP_2 = (1<<16) | (int)(FOO.FOO_2),
    // etc
}
于 2012-10-12T00:52:03.310 に答える
2

MASK定義されているものに置き換えるだけです(<<および|演算子はC#にも存在します):

enum DISP
{
    DISP_1 = ((1 << 16) | FOO.FOO_1),
    DISP_2 = ((1 << 16) | FOO.FOO_2)
}

シフトや演算子が正確に何をするのか疑問に思っている場合は、のバイナリ値を取得して、000000000000000116の値を左にシフトします1000000000000000

別の例は、に(000001101 << 3)なり001101000ます。

or演算子は、いずれかのオペランドから1つの値をすべて取得し、結果の値を1に設定します。

たとえば、に0001 | 0110なり0111ます。

それでは、DISP_2を取ります。

  (0b00000000000000001 << 16) | 0b00000000000000010)
= (0b10000000000000000 | 0b00000000000000010)
= (0b10000000000000010)
= 65538

(この0b形式はC#では機能せず、Cでは標準ではありませんが、16進数ではなく、2進数表記を使用する方が便利で、演算子の動作を簡単に確認できます)

于 2012-10-12T00:51:34.633 に答える
0

DISP_xが等しい数値:

DISP_1 == 0x10000
DISP_2 == 0x10001
DISP_3 == 0x10002
...
于 2012-10-12T00:54:30.220 に答える
0

ビットシフト演算子はC#で機能しますが、defineマクロは機能しません。

何が起こっているのかを理解するには、値を個別に計算してから列挙型に入れることです。

もちろん、それ|がビット単位のOR演算子であることはご存知でしょう。そして、オペレーター<<が行うことは、バイナリを左にシフトすることである場合に備えて:

1 << 16 = 10000000000000000_2 //those are 16 zeroes and _2 indicates binary

順番に:

10000000000000000_2 = 65536

これは、2番目のオペランドで示される回数だけ2を掛けるのと同じです。

1 << 1 = 2
1 << 2 = 4
1 << 3 = 8

そうです、それは数に2の累乗を掛けています:

1 << 1 <=> 1 * 2^1 = 2
1 << 2 <=> 1 * 2^2 = 4
1 << 3 <=> 1 * 2^3 = 8

さて、それFOO_1 = 0以来

DISP_1 = MASK(FOO_1)
=>
DISP_1 = ((1 << 16) | (FOO_1))
=>
DISP_1 = (65536 | (FOO_1))
=>
DISP_1 = (65536 | FOO_1)
=>
DISP_1 = (65536 | 0)
=>
DISP_1 = 65536

私が取るのと同じことをするとFOO_2、値は1になります。

DISP_2 = (65536 | FOO_2)
=>
DISP_2 = (65536 | 1)
=>
DISP_2 = 65537

そうは言っても、以下は正しく機能します。

enum FOO
{
    FOO_1 = 0,
    FOO_2,
    // etc
}

enum DISP
{
    DISP_1 = (1<<16) | (int)(FOO.FOO_1),
    DISP_2 = (1<<16) | (int)(FOO.FOO_2),
    // etc
}
于 2012-10-12T00:55:27.700 に答える