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 在二进制中是 11,因此结果将是 10000000000000011。这在功能上与将 65,536 加到每个值相同。

现在,当我们声明第二个枚举时,我们将这些枚举值的值设置为这个奇怪的屏蔽函数。

要在 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)通过对带有二进制数的数字进行OR-ing构造一个数字(向左移动 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为定义的内容(<<and|运算符也存在于 C# 中):

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

如果您想知道 shift 和 or 运算符到底是做什么的,那么您将获取 的二进制值0000000000000001并将其向左移动 16 个值:1000000000000000.

另一个例子,(000001101 << 3)变成001101000

or 运算符从任一操作数中获取所有 1 值并将结果的值设置为 1。

例如,0001 | 0110变成0111

那么,以 DISP_2 为例:

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

(我知道该0b格式在 C# 中不起作用,在 C 中也不是标准格式,但使用二进制表示法而不是十六进制更有用,更容易看到运算符在做什么)

于 2012-10-12T00:51:34.633 回答
0

位移位运算符在 C# 中有效,但定义宏不可用。

要了解发生了什么,您可以做的是分别计算这些值,然后将它们放入枚举中。

当然你知道那|是按位或运算符。以防万一操作员<<将二进制文件向左移动:

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

反过来:

10000000000000000_2 = 65536

这相当于将数字乘以第二个操作数指示的次数。

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 回答
0

DISP_x 相等的数值:

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