C 语言(C99) 对 64 位整数类型的支持
前几天跟同事闲聊 64 位操作系统时,有人问起 64 位平台上,C 语言的数据类型如何确定的问题。以及跨平台(跨 16 位、32 位和 64 位平台)程序如何选用合适的数据类型。
我查了一下资料,记录如下:
char 通常被定义成 8 位宽。
int 通常被定义成 16 位或 32 位宽(或更高),它取决于平台。编译器将在这两者间选择最合适的字宽。
short 通常被定义成 16 位宽。
long 通常被定义成 32 位宽。
C99 为 C 语言扩展了新的整数类型 long long ,通常被定义成 64 位宽。(GNU C 亦支持)
但是 C 标准并没有定义具体的整数类型的宽度,只定义了 long long 的级别高于 long ,long 的级别高于 int ,int 的级别高于 short ,short 的级别高于 char 。(另外有 _Bool
永远是最低级别)。级别高的整数类型的宽度大于等于级别较低的整数类型。
char 的宽度用宏 CHAR_BIT
定义出来,通常为 8 ,而除了位域类型外,其它所有类型的位宽都必须是它的整数倍。
如果需要精确确定整数类型的宽度,在 C99 以及 GNU C 中,需要包含 stdint.h ,使用其中几种扩展的整数类型。
int16_t
可以保证整数长度为精确的 16 位。同样,int8_t
可以保证整数长度为精确的 8 位。类似的还有 int32_t
int64_t
以及无符号类型 uint8_t
等等。
int_least16_t
可以得到一个当前平台所支持的至少有 16 位宽的最短整数类型。(其它同类型的可以类推)
int_fast32_t
可以得到当前平台下得到处理速度最快的至少为 32 位的整数类型。
intmax_t
可以获得当前平台所支持的最大宽度的整数类型。
在书写整数常数时,在数字后加上 L 表示是一个 long 类型的整数,加上 U 表示是一个 unsigned 整数,加上 LL 表示是一个 long long 类型整数。但是由于 long long 这些并不能确定准确字宽,有此需求时,可以借助宏 INTn_C(value)
来转换。例如,想指定一个 64 位整数常数 0x1234 ,可以写成 INT64_C(0x1234) 。若在当前平台上 int_least64_t
就是 long long int 的话,这个宏会被展开成 0x1234LL 。
最后再提一个很重要的扩展类型:intptr_t
(无符号版本写成 uintptr_t
)这个类型可以被安全的在 void * 和 整数间转换,对于写跨 64 位平台的程序非常重要。也就是说,当你需要把指针作为一个整数来运算时,转换成 intptr_t
才是安全的,可以在运算完毕安全的转回指针类型。
C 语言中,指针和整数之间的转换经常用到(多用于需要精确控制数据在内存中的精确布局时),在 32 位平台上,由于指针类型的字宽和 int 相同,所以我们不太在意这个问题。但是到了 64 位平台上,由于目前几乎所有 64 位系统都采用 LP64 模型,既整数依旧是 32 位,而指针是 64 位的。intptr_t
这个数据类型就成了安全跨平台编程的保证。
Comments
Posted by: 御宅暴君 | (9) April 2, 2014 05:26 PM
Posted by: WaterWalk | (8) January 16, 2008 07:47 PM
Posted by: 天堂的隔壁 | (7) January 7, 2008 09:16 AM
Posted by: nothanks | (6) January 7, 2008 09:16 AM
Posted by: Cloud | (5) January 6, 2008 02:55 PM
Posted by: jack | (4) January 6, 2008 11:03 AM
Posted by: Solstice | (3) January 6, 2008 08:24 AM
Posted by: chengmeng | (2) January 5, 2008 11:36 PM
Posted by: 知名不具 | (1) January 5, 2008 05:24 PM