十六进制表达式0x80000000在C语言的枚举声明中是什么意思?



我正在阅读一个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 compiler 4.2, EVENT_EXIT = (int) -2147483648, EVENT_RELEASE_TOUCH = (int) -2147483645等。

显然,它们被处理在2的补表示中。相关文章可以在这里找到。

但我现在不确定的是:

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

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

请分享一些想法。D

和许多类c语言一样,枚举只是一个整数。像这样设置第一个值将导致编译器从那里开始自增,从而保证所有枚举值都小于0。(作为一个有符号整数的2s恭维,被设置的高位将表示一个负数)

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

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

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

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

108)一个实现可能会延迟整数类型的选择,直到所有枚举常量都被看到。

  1. 枚举的类型是int。
  2. 0x80000000只是一个数字,但采用十六进制表示法。它的值是您在调试器(或任何十六进制到十进制转换器)中确认的值。
  3. 枚举的工作方式是从任何显式赋值的值中增量地赋值。因此,在这种情况下,枚举被分配为EVENT_EXIT=0x80000000, EVENT_TOUCH=0x80000001, EVENT_DRAG=0x80000002,等等。

enum的底层类型取决于它需要保存的值。编译器在如何最终定义该类型上有一定的自由度。在您的例子中,Application_Events的底层类型很可能是unsigned int,因为它大于INT_MAX,假设int的大小是32位(enum通常是32位)。比如:

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 s),它的值取决于平台和使用的C版本。

2)对于实际情况,您可以假设您的处理器将支持2的补码算法,因为大多数平台都使用它。然而,C语言本身并不保证。其他算术格式(1的补码,有符号的大小)也是允许的。

最新更新