在C语言中,int类型是否总是32位?

23

这与以下问题有关,

如何在C语言中声明32位整数

许多人提到int是大多数平台上始终为32位。我很好奇是否属实。

您知道是否有任何使用不同大小的int的现代平台吗?请忽略具有8位或16位架构的恐龙平台。

注意:我已经知道如何从其他问题中声明32位整数。这更像是一项调查,以了解支持其他大小的整数的平台(CPU / OS / Compiler)。


11
现代的8位和16位处理器确实存在,只是它们不在个人电脑环境中使用。 - Gerhard
8个回答

44

正如其他人所说,不能保证一个'int'类型的变量一定是32位,如果你想使用特定大小的变量,尤其是在编写涉及位操作的代码时,你应该使用c99规范所规定的“标准整数类型”。

int8_t
uint8_t
int32_t
uint32_t

它们通常采用[u]intN_t的格式,其中“u”指定您想要无符号量,N是位数。

这些类型应在stdint.h中以正确的typedef形式提供,无论您在哪个平台上编译,使用它们可以让您编写漂亮、可移植的代码 :-)


当然,我刚刚检查了一下,我认为这在Windows上有问题:http://blogs.msdn.com/oldnewthing/archive/2005/01/31/363790.aspx但那听起来不太对,所以我要在我兄弟的Windows机器上再次检查。 - Robert Massaioli
1
请注意,这些类型在 C99 中是可选的。如果实现提供了具有正确属性的基础类型,则必须为您提供相应的 [u]intN_t 类型,但不能保证实现将具有此类类型。然而,它们会很少出现,因此如果您的编译器符合 C99 标准,则这可能是最佳方法。 - paxdiablo
2
@paxdiablo “{,u}int_{least,fast}{8,16,32,64}_t”类型虽然在C99(§7.18.1.1)中是必需的,但它们可以用于几乎相同的目的--唯一的注意事项是它们仅被保证至少(而不是完全)为8/16/32/64位宽。 - Craig Barnes
很好的观点,@Craig,此回答中明确列出的类型可能不是最宽泛的,但您始终可以使用更广泛的类型,并忽略第32位左侧的任何位。 - paxdiablo

17

"在大多数平台上,通常情况下,它的位数始终为32位" - 这段代码有什么问题? :-)

C标准并没有规定其许多整数类型的大小。它确实规定了相对大小,例如,sizeof(int) >= sizeof(short)等。它还规定了最小范围,但允许使用多种编码方案(二进制补码、反码和原码)。

如果您想要一个特定大小的变量,需要使用适合所在平台的变量,例如使用#ifdef,类似于:

#ifdef LONG_IS_32BITS
    typedef long int32;
#else
    #ifdef INT_IS_32BITS
        typedef int int32;
    #else
        #error No 32-bit data type available
    #endif
#endif

另外,C99及以上版本支持精确宽度整数类型intN_tuintN_t


  1. typedef名称intN_t指定了一个带有宽度N、没有填充位以及二进制补码表示的有符号整型。因此,int8_t表示一个宽度恰好为8位的有符号整数类型。
  2. typedef名称uintN_t指定了一个带有宽度N的无符号整型。因此,uint24_t表示一个宽度恰好为24位的无符号整数类型。
  3. 这些类型是可选的。但是,如果实现提供了宽度为8、16、32或64位、没有填充位并且(对于有符号类型)具有二进制补码表示的整数类型,则应定义相应的typedef名称。

2
抢先一步了 :) 在 C 或 C++ 中依赖内置变量的大小本质上是一个错误。 - kyoryu
8
C语言标准规定了最小范围(意味着最小大小)。int的最小范围是-32767到+32767,而long的最小范围是-2147483647到+2147483647。 - caf
3
这意味着,如果你只需要一个能够存储32位整数范围的变量,就使用 long 或 unsigned long - 不需要使用预处理器技巧。 - caf
3
@Justin,你可能晚了一些,但似乎是在过去的三年中唯一注意到这个问题的人。很好地发现了这个问题,并已经进行了更改修复。 - paxdiablo
3
@caf: 即使 int 能够胜任,但总是使用 long 似乎有些愚蠢。我需要一个能存储从0到999,999,999的数字的变量,而且不想它的宽度为64位(如 long 有时会有的),32位就足够了。看起来很奇怪,整数类型 intN_t 最初没有可用。他们意识到不同比特宽度的CPU将运行C软件,但在30年内他们并没有费心去保证比特宽度的可移植性? - ArtOfWarfare
显示剩余3条评论

9

目前大多数桌面和服务器平台使用32位整数,甚至许多嵌入式平台(如手持式ARM或x86)也使用32位int。要获得16位int,您必须变得非常小:考虑“伯克利微粒”或一些较小的Atmel Atmega芯片。但是它们确实存在。


2
太好了,这是唯一一个真正回答问题的答案!不过,知道你得到这个答案的来源以及使用32位的特定编译器/平台或者不使用32位的编译器/平台会非常好。 - Winter Dragoness

6

许多小型嵌入式系统使用16位整数。


1
有趣的事实:在一些TI DSPs上,例如C2000,sizeof(int) == 1charint都有16位(当然还有short)。 - starblue

2

这主要取决于您使用的编译器。一些编译器在64位机器上编译为64位,而一些则编译为32位。嵌入式系统是一个特殊的领域。

最好的检查方法:

printf("%d\n", sizeof(int));

请注意,sizeof将打印出字节。使用sizeof(int)*CHAR_BIT可获取位数。
以下是打印各种类型位数的代码:
#include <limits.h>
#include <stdio.h>

int main(void) {
    printf("short is %d bits\n",     CHAR_BIT * sizeof( short )   );
    printf("int is %d bits\n",       CHAR_BIT * sizeof( int  )    );
    printf("long is %d bits\n",      CHAR_BIT * sizeof( long )    );
    printf("long long is %d bits\n", CHAR_BIT * sizeof(long long) );
    return 0;
}

1
这里有很多错误。首先,sizeof可以操作类型,所以不需要randomint。其次,CHAR_BITS不能保证为八位。还有一些其他问题,但这些是与问题相关的错误。 - Sinan Ünür
一个字节不总是8位,这是真的。 - Ed S.
@Eric,应该是 CHAR_BIT。我在评论中拼错了。 - Sinan Ünür
2
它也不能保证类型底层表示中的每个位都是有效位 - 你可能有溢出位(或甚至填充位)。 - caf

1

TI仍在销售带有C55x DSP的OMAP板,主要用于视频解码。我相信为此提供的编译器具有16位int。它几乎不是恐龙(Nokia 770于2005年发布),尽管您可以获得32位DSP。

大多数您编写的代码,您可以安全地假设它永远不会在DSP上运行。但也许并非全部。


0

大多数基于ARM的处理器都可以运行Thumb代码,这是一种16位模式。这包括尚未公布的Android笔记本电脑和最先进的智能手机。

此外,一些图形计算器使用8位处理器,我认为这些也相当现代化。


2
如果使用8位整型,就无法实现符合规范的C语言实现,所以即使那些计算器采用8位架构,但只要它们内置C编译器,就必须将整型至少扩展到16位。 - Steve Jessop
1
Thumb代码仍然使用32位整数;“16位”方面只是编码指令的大小。 - Matthew Wightman
在 ANSI C 标准中,int 和 short int 的最小可接受大小为 16 位,因此无法使用 8 位。:) - Samia Ruponti

0
如果你对实际的最大/最小值感兴趣而不仅仅是位数,limits.h 包含了你想要知道的几乎所有信息。

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