类似于“1 << 0”的typedef枚举语法是什么意思?

8

我对C和C++中的typedef enum语法有些了解。现在我正在使用Objective-C进行编程,并遇到了以下示例中的语法。我不确定这种语法是否特定于Objective-C。但是,我的问题是在以下代码片段中,像1 << 0这样的语法是什么意思?

typedef enum {
   CMAttitudeReferenceFrameXArbitraryZVertical = 1 << 0,
   CMAttitudeReferenceFrameXArbitraryCorrectedZVertical = 1 << 1,
   CMAttitudeReferenceFrameXMagneticNorthZVertical = 1 << 2,
   CMAttitudeReferenceFrameXTrueNorthZVertical = 1 << 3
} CMAttitudeReferenceFrame;

感谢Carl的帖子。只是提醒一下,我在发帖之前确实进行了搜索。但我不知道它被称为位移操作。 - MikeyE
没问题,这就是我们在这里的原因。=) - Carl Norum
你的问题在这里得到了回答:定义SOMETHING (1 << 0),要理解<<运算符,请参考vies this - Grijesh Chauhan
我看到有人将我的问题标记为重复。在发布我的问题之前,我查看了标题为“绝对初学者的位移指南”的文章。我的问题不是重复的,因为我指定了我的问题是针对Objective-C特定的。虽然我知道Objective-C源自C语言,但苹果可能已经向Objective-C添加了一些额外的位移功能。因此,我提出了针对Objective-C的问题。 - MikeyE
3个回答

14

这种方法在C语言家族中很常见,且在C、C++和Objective-C中的表现相同。与Java、Pascal和类似语言不同,C枚举类型不仅限于为其命名的值;它实际上是一个整数类型,大小足以表示所有命名值,并且可以将枚举类型的变量设置为枚举成员中的算术表达式。通常使用位移操作使值为2的幂,并使用按位逻辑运算符组合值。

typedef enum {
   read    = 1 << 2,  // 4
   write   = 1 << 1,  // 2
   execute = 1 << 0   // 1
} permission;  // A miniature version of UNIX file-permission masks

再次强调,所有的位移操作都来自C语言。

现在你可以编写:

permission all = read | write | execute;
你甚至可以在权限声明中包含那一行:

你甚至可以在权限声明中包含那一行:

typedef enum {
   read    = 1 << 2,  // 4
   write   = 1 << 1,  // 2
   execute = 1 << 0,  // 1
   all     = read | write | execute // 7
} permission;  // Version 2

如何为文件打开执行权限?

filePermission |= execute;

请注意这是危险的:

filePermission += execute;

这将把值为all的某些内容更改为8,这没有任何意义。


3
+1 目前为止最好的答案。 - Shafik Yaghmour
2
非常好的答案。非常清晰简洁。谢谢! - MikeyE

6

3

看起来 typedef 代表一个位域值。 1 << n 是将 1 左移 n 位。因此,每个 enum 项代表不同的位设置。该特定的位设置或清除指示某些东西处于两种状态之一。左移零位的 11

如果声明了一个数据:

CMAttitudeReferenceFrame foo;

然后您可以使用enum值检查其中任意一个独立状态,而foo不会超过int的大小。例如:

if ( foo & CMAttitudeReferenceFrameXArbitraryCorrectedZVertical ) {
    // Do something here if this state is set
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接