201

C中的整数变量是占用2字节还是4字节?它取决于哪些因素?

大多数教科书都说整数变量占用 2 个字节。但是当我运行一个打印整数数组的连续地址的程序时,它显示的差异为 4。

4

13 回答 13

213

我知道它等于sizeof(int)。an 的大小int实际上取决于编译器。过去,当处理器是 16 位时,anint是 2 个字节。如今,在 32 位和 64 位系统上它通常是 4 个字节。

尽管如此,使用sizeof(int)是获取执行程序的特定系统的整数大小的最佳方法。

编辑:int修复了大多数 64 位系统上 8 个字节的错误语句。例如,在 64 位 GCC 上是 4 个字节。

于 2012-07-11T18:14:57.500 回答
114

这是 C 语言中一开始可能令人困惑的一点,但 C 语言标准仅指定了保证支持的整数类型的最小范围。int保证能够保持-32767到32767,这需要16位。在这种情况下,int, 是 2 个字节。但是,实现可以自由地超出该最小值,因为您会看到许多现代编译器都生成int32 位(这也意味着 4 字节非常普遍)。

你的书说 2 个字节的原因很可能是因为它太旧了。一度,这是常态。一般来说,sizeof如果您需要了解它在您正在使用的平台上的字节数,您应该始终使用该运算符。

为了解决这个问题,C99 添加了新类型,您可以在其中显式请求特定大小的整数,例如int16_tor int32_t。在此之前,没有通用的方法来获取特定宽度的整数(尽管大多数平台在每个平台的基础上都提供了类似的类型)。

于 2012-07-11T18:24:52.113 回答
35

没有具体的答案。这取决于平台。它是实现定义的。它可以是 2、4 或其他。

背后的想法int是它应该与给定平台上的自然“字”大小相匹配:16 位平台上的 16 位,32 位平台上的 32 位,64 位平台上的 64 位,你明白了。但是,出于向后兼容的目的,一些编译器更喜欢坚持使用 32 位int,即使在 64 位平台上也是如此。

2 字节的时代int已经一去不复返了(16 位平台?),除非您使用的是具有 16 位字长的嵌入式平台。你的教科书可能很旧了。

于 2012-07-11T18:15:00.047 回答
20

这个问题的答案取决于您使用的平台。
但无论平台如何,您都可以可靠地假设以下类型:

 [8-bit] signed char: -127 to 127
 [8-bit] unsigned char: 0 to 255
 [16-bit]signed short: -32767 to 32767
 [16-bit]unsigned short: 0 to 65535
 [32-bit]signed long: -2147483647 to 2147483647
 [32-bit]unsigned long: 0 to 4294967295
 [64-bit]signed long long: -9223372036854775807 to 9223372036854775807
 [64-bit]unsigned long long: 0 to 18446744073709551615
于 2014-03-14T12:14:13.520 回答
16

C99 N1256标准草案

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

的大小int和所有其他整数类型都是实现定义的,C99 仅指定:

  • 最小尺寸保证
  • 类型之间的相对大小

5.2.4.2.1 “整数类型<limits.h>的大小”给出了最小大小:

1 [...] 它们的实现定义值的大小(绝对值)应等于或大于所示的 [...]

  • UCHAR_MAX 255 // 2 8 - 1
  • USHRT_MAX 65535 // 2 16 - 1
  • UINT_MAX 65535 // 2 16 - 1
  • ULONG_MAX 4294967295 // 2 32 - 1
  • ULLONG_MAX 18446744073709551615 // 2 64 - 1

6.2.5“类型”然后说:

8 对于任何两个具有相同符号和不同整数转换等级的整数类型(见 6.3.1.1),具有较小整数转换等级的类型的值范围是另一个类型的值的子范围。

和 6.3.1.1 “布尔、字符和整数”确定相对转换等级:

1 每个整数类型都有一个整数转换等级,定义如下:

  • long long int 的rank 大于long int 的rank,long int 的rank 大于int 的rank,short int 的rank 大于signed char 的rank。
  • 任何无符号整数类型的等级应等于相应的有符号整数类型的等级,如果有的话。
  • 对于所有整数类型 T1、T2 和 T3,如果 T1 的秩大于 T2 且 T2 的秩大于 T3,则 T1 的秩大于 T3
于 2016-05-09T19:44:02.727 回答
13

C中的整数变量是占用2字节还是4字节?

这取决于您使用的平台以及编译器的配置方式。唯一权威的答案是使用sizeof运算符来查看在您的特定情况下整数有多大。


它取决于哪些因素?

最好考虑Range,而不是size。两者在实践中都会有所不同,尽管我们将看到,按范围选择变量类型比按大小选择变量类型要简单得多。同样重要的是要注意,标准鼓励我们考虑根据范围而不是大小来选择整数类型,但现在让我们忽略标准做法,让我们的好奇心探索sizeof字节CHAR_BIT和整数表示......让我们深入研究兔子洞,亲眼看看……


sizeof,字节和CHAR_BIT

以下语句取自 C 标准(链接到上面),用我认为无法改进的语言描述了这一点。

运算符产生其sizeof操作数的大小(以字节为单位),它可以是表达式或带括号的类型名称。大小由操作数的类型决定。

假设一个清晰的理解将引导我们讨论字节。通常假设一个字节是八位,而实际上CHAR_BIT告诉您一个字节中有多少位。这只是在谈论常见的两个(或四个)字节整数时没有考虑的另一个细微差别。

到目前为止,让我们总结一下:

  • sizeof=> 以字节为单位的大小,以及
  • CHAR_BIT=> 字节中的位数

因此,根据您的系统,sizeof (unsigned int)可以是任何大于零的值(不仅仅是 2 或 4),就像CHAR_BIT是 16,那么单个(16 位)字节中有足够的位来表示由标准(引用如下)。这不一定是有用的信息,是吗?让我们更深入地研究...


整数表示

C 标准在此处指定所有标准整数类型(以及CHAR_BITfwiw)的最小精度/范围。由此,我们可以得出存储该值需要多少位的最小值,但我们也可以根据范围选择变量。尽管如此,这个答案所需的大部分细节都在这里。例如,标准需要(至少)十六位存储的以下内容:unsigned int

UINT_MAX                                65535 // 2¹⁶ - 1

因此,我们可以看到unsigned int需要(至少)16 位,这是您获得两个字节(假设CHAR_BIT是 8)的地方......后来当该限制增加到 时2³² - 1,人们改为使用 4 个字节。这解释了您观察到的现象:

大多数教科书都说整数变量占用 2 个字节。但是当我运行一个打印整数数组的连续地址的程序时,它显示的差异为 4。

你正在使用一本古老的教科书和编译器,它教你不可移植的 C;写你教科书的作者可能甚至都不知道CHAR_BIT。您应该升级您的教科书(和编译器),并努力记住 IT 是一个不断发展的领域,您需要在竞争中保持领先……不过,这已经够了;让我们看看那些底层整数字节存储的其他不可移植的秘密......

价值位似乎是常见的误解。上面的例子使用了一个unsigned整数类型,它通常只包含值位,所以很容易在细节上错过魔鬼。

符号位...在上面的示例中,我引用UINT_MAX了作为上限,unsigned int因为16从注释中提取值是一个简单的示例。对于有符号类型,为了区分正负值(即符号),我们还需要包含符号位。

INT_MIN                                -32768 // -(2¹⁵)
INT_MAX                                +32767 // 2¹⁵ - 1

填充位......虽然在整数中遇到具有填充位的计算机并不常见,但 C 标准允许这种情况发生;一些机器(即台机器)通过将两个较小的(有符号)整数值组合在一起来实现更大的整数类型......当您组合有符号整数时,您会得到一个浪费的符号位。浪费的位在 C 中被认为是填充。填充位的其他示例可能包括奇偶校验位和陷阱位


如您所见,该标准似乎鼓励在选择整数类型时考虑诸如INT_MIN..之类的范围INT_MAX以及标准中的其他最小值/最大值,并且不鼓励依赖大小,因为还有其他可能被遗忘的微妙因素,例如CHAR_BIT填充位可能会影响 的值sizeof (int)(即对两字节和四字节整数的常见误解忽略了这些细节)。

于 2012-07-11T18:15:06.760 回答
8

唯一的保证是char必须至少8 位宽,short并且int必须至少16 位宽,并且long必须至少32 位宽,并且sizeof (char)<= sizeof (short)<= sizeof (int)<= sizeof (long)(对于这些类型的无符号版本也是如此)。

int根据平台的不同,宽度可能在 16 到 64 位之间。

于 2012-07-11T18:35:42.553 回答
8

C“int”的大小是 2 字节还是 4 字节?

答案是“是”/“否”/“也许”/“也许不是”。

C 编程语言指定以下内容:最小的可寻址单元,char也称为“字节”,正好是CHAR_BIT位宽,其中CHAR_BIT至少为 8。

因此,C 中的一个字节不一定是八位字节,即 8 位。在过去,第一个运行 C 代码(和 Unix)的平台有 4 字节int- 但总共int有 36 位,因为CHAR_BIT是 9!

int应该是平台的自然整数大小,其范围至少为-32767 ... 32767. 您可以使用;获取int平台字节的大小 sizeof(int)当您将此值乘以时,CHAR_BIT您将知道它的位宽。


虽然 36 位机器大多已死机,但仍有一些平台使用非 8 位字节。就在昨天,有一个关于 16 位字节的德州仪器 MCU 的问题,它具有符合 C99、C11 的编译器。

TMS320C28xchar上,short和似乎int都是16 位宽,因此是一个字节long int是 2 个字节,long long int是 4 个字节。C 语言的美妙之处在于,仍然可以为这样的平台编写高效的程序,甚至可以以可移植的方式完成!

于 2018-11-09T07:49:54.173 回答
5

大多数情况下,它取决于您使用的平台。它取决于编译器到编译器。现在在大多数编译器中,int4 个字节。如果你想检查你的编译器正在使用什么,你可以使用sizeof(int).

main()
{
    printf("%d",sizeof(int));
    printf("%d",sizeof(short));
    printf("%d",sizeof(long));
}

c编译器唯一承诺的是short的大小必须等于或小于int,long的大小必须等于或大于int。所以如果int的大小是4,那么short的大小可能是2或4但不能更大比那个。long 和 int 也是如此。它还说短和长的大小不能相同。

于 2014-01-30T14:24:29.093 回答
3

这取决于实现,但通常在 x86 和其他流行的架构(如 ARM )上int占用 4 个字节。您始终可以在编译时使用sizeof(int)或您想要检查的任何其他类型进行检查。

如果要确保使用特定大小的类型,请使用<stdint.h>

于 2012-07-11T18:15:02.150 回答
2
#include <stdio.h>

int main(void) {
    printf("size of int: %d", (int)sizeof(int));
    return 0;
}

这将返回 4,但它可能取决于机器。

于 2012-07-11T18:15:18.127 回答
1

C“int”的大小是 2 字节还是 4 字节?

C中的整数变量是占用2字节还是4字节?

C 允许“字节”不是每个“字节”8 位。

CHAR_BIT不是位域(字节)的最小对象的位数 C11dr §5.2.4.2.1 1

大于 8 的值越来越少见。为了获得最大的可移植性,请使用CHAR_BIT而不是 8。C 中intin的大小 为sizeof(int) * CHAR_BIT.

#include <limits.h>
printf("(int) Bit size %zu\n", sizeof(int) * CHAR_BIT);

它取决于哪些因素?

int位大小通常为 32 或 16 位。C 规定的最小范围

int INT_MIN-32767类型对象的最小值+32767
类型对象的最大值 C11dr §5.2.4.2.1 1int INT_MAX

强制位大小至少为16的最小范围- 即使处理器是“8 位”。在专用处理器中可以看到像 64 位这样的大小。其他值,如 18、24、36 等,已经出现在历史平台上,或者至少在理论上是可能的。现代编码很少担心非 2 次方位大小。intint

计算机的处理器和架构驱动int位大小的选择。

然而,即使使用 64 位处理器,int出于兼容性原因,编译器的大小也可能是 32 位,因为大型代码库取决于int32 位(或 32/16)。

于 2018-01-14T21:33:26.373 回答
-1

这是回答这个问题的一个很好的来源。

但这个问题是一种永远真实的回答“是的。两者兼而有之。”

这取决于您的架构。如果您要在 16 位或更少的机器上工作,它不能是 4 字节(=32 位)。如果您在 32 位或更好的机器上工作,它的长度是 32 位。

为了弄清楚,让你的程序准备好输出可读的东西并使用“sizeof”函数。这将返回您声明的数据类型的字节大小。但是在数组中使用它时要小心。

如果您声明int t[12];它将返回 12*4 字节。要获取此数组的长度,只需使用sizeof(t)/sizeof(t[0]). 如果您要构建一个函数,它应该计算发送数组的大小,请记住,如果

typedef int array[12];
int function(array t){
    int size_of_t = sizeof(t)/sizeof(t[0]);
    return size_of_t;
}
void main(){
    array t = {1,1,1};  //remember: t= [1,1,1,0,...,0]
    int a = function(t);    //remember: sending t is just a pointer and equal to int* t
   print(a);   // output will be 1, since t will be interpreted as an int itselve. 
}

所以这甚至不会返回不同的东西。如果您定义了一个数组并尝试在之后获取长度,请使用 sizeof。如果将数组发送给函数,请记住发送值只是第一个元素上的指针。但在第一种情况下,你总是知道你的数组有多大。情况二可以通过定义两个函数来解决,但会错过一些性能。定义函数(数组 t)并定义函数 2(数组 t,int size_of_t)。调用“function(t)”通过一些复制工作来测量长度并将结果发送到 function2,在那里你可以对可变数组大小做任何你想做的事情。

于 2017-09-11T16:27:13.630 回答