1

我正在阅读 iPhone 示例项目的代码(Xcode IDE,Apple LLVM 编译器 4.2)。在该 iPhone 示例项目的外部库(用 C 编写)的头文件中,在枚举类型中声明了一些事件:

typedef enum _Application_Events
{
    EVENT_EXIT = 0x80000000,
    EVENT_TOUCH,
    EVENT_DRAG,
    EVENT_RELEASE_TOUCH,
    EVENT_ROTATE_0,
    EVENT_ROTATE_90,
    EVENT_ROTATE_180,
    EVENT_ROTATE_270
} Application_Events;

我不明白为这些事件分配了什么样的值。0x80000000应该是一个大的正整数 ( ) 2147483648,还是负零,还是一个负整数 ( -2147483648)?

我在 Xcode 调试器中进行了检查,编译器是 Apple LLVM 编译器 4.2、EVENT_EXITequals(int) -2147483648EVENT_RELEASE_TOUCHequals(int) -2147483645等等。

显然,它们以二进制补码表示形式处理。可以在此处找到相关帖子。

但我现在不确定的是这些:

0x80000000(1) 在其他情况下总是存在int或其他东西的基础数据类型?这取决于编译器还是平台?

(2) 如果我为这样的有符号整数分配了一个十六进制值,它是否总是被解释为二进制补码表示?这取决于编译器还是平台?可以在此处找到相关帖子。另一个参考可以在这里找到。

请分享一些想法。谢谢大家 :D

4

4 回答 4

3

像 C 语言中的许多东西一样,枚举只是一个整数。像这样设置第一个值将导致编译器从那里递增,保证所有枚举值都小于 0。(作为 2s 补码的有符号整数,设置的高位将指示负数)

很可能,程序员选择这个值是为了能够发送各种事件,并且不应该与其他事件发生冲突。

简而言之,不要担心实际价值;这只是一个数字。使用名称并理解这应该是使用或返回这些代码的调用的上下文中的含义。

于 2013-04-23T03:25:13.837 回答
2

枚举的基本类型是实现定义的。在这种情况下,基类型应该是unsigned int,因为标准要求编译器选择一个足够宽以容纳所有枚举值的基类型。根据 C99 标准,第 6.7.2.2.4 节:

每个枚举类型应与char有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,108)但应该能够表示枚举的所有成员的值。枚举类型在}终止枚举器声明列表之前是不完整的。

108) 实现可能会延迟选择哪种整数类型,直到看到所有枚举常量。

于 2013-04-23T03:23:43.407 回答
1

的基础类型enum取决于它需要持有的值。编译器对如何最终定义该类型有一定的自由度。在您的情况下,基础类型很可能Application_Eventsunsigned int因为它大于INT_MAX,假设它int的大小是 32 位(enum通常是什么)。但是像:

enum foo_t {
   FOO_Start,
   FOO_Thing,
   FOO_Another_Thing,
   FOO_End
};

的类型enum foo_t可以是intunsigned int

但是,枚举常量(例如 ,EVENT_EXITFOO_Start)是 类型int。这就是您在调试器中看到的。如果你做类似的事情

Application_Events foo = EVENT_EXIT;

的类型foo可能是unsigned。我认为这个问题发生了一些变化,所以:

1)对于 iPhone,常数0x80000000可能是unsigned(iPhone ARM 处理器有 32 位int)。它的值取决于平台和使用的 C 版本。

2) 对于实际情况,您可以假设您的处理器将支持二进制补码算法,因为大多数平台都使用它。然而,C 语言本身并不能保证这一点。允许使用其他算术方案(反码、有符号幅度)。

于 2013-04-23T03:28:00.473 回答
1
  1. 枚举的类型是 int。
  2. 0x80000000 只是一个数字,但以十六进制表示。它的值是您在调试器(或任何十六进制到十进制转换器)中确认的值。
  3. 枚举的工作方式是从任何显式分配的值逐步分配值。因此,在这种情况下,枚举被分配为 EVENT_EXIT=0x80000000、EVENT_TOUCH=0x80000001、EVENT_DRAG=0x80000002 等等。
于 2013-04-23T03:54:02.550 回答