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


168

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

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



1
int只是几种整数类型之一。您询问“整数”的大小;您可能想问一下的大小int
基思·汤普森

3
而且您应该找到更好的教科书。一本教科书上说an int为2个字节,(a)可能是指旧系统,而(b)未能明确说明大小会因一个系统而异。关于C的最佳书籍是Kernighan和Ritchie撰写的“ The C Programming Language”,尽管它具有一定的编程经验。另请参阅comp.lang.c FAQ的问题18.10 。
基思·汤普森

2
请尝试#define int int64_t在64位平台上使用,但两者都不行。只需使用sizeof。;-)
netcoder

Answers:


183

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

仍然,使用 sizeof(int)对于执行程序的特定系统还是获取整数大小的最佳方法。

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


31
@RajivPrathap:嗯,这取决于编译器,但是编译器决定它是否也取决于机器。:)
user541686

2
如果需要预处理程序的大小,则可以检查预定义的宏,例如INT_MAX。如果该值不是您的代码期望的值,则int的字节大小在当前的编译器/平台组合上会有所不同。
Walt Sellers 2014年

3
不仅取决于机器,还取决于机器上运行的操作系统。例如,在Win64中long是4个字节,而在Linux64中long是8个字节。
Cem Kalyoncu 2015年

9
错误。在大多数64位系统上,int仍为4字节en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv 2015年

7
sizeof(int)可以是中的任何值1。字节不需要是8位,并且某些机器没有8位可寻址单元(这基本上是标准中字节的定义)。没有更多信息,答案是不正确的。
对于这个网站来说太老实了

102

这是C语言中一开始可能会引起混淆的要点之一,但是C标准仅指定了保证可以支持的整数类型的最小范围int保证能够容纳-32767到32767,这需要16位。在这种情况下,int是2个字节。但是,实现可以自由地超出该最低要求,因为您将看到许多现代编译器使用int32位(这也意味着4字节无处不在)。

您的书说2个字节的原因很可能是因为它太旧了。曾经这是常态。通常,sizeof如果需要找出正在使用的平台上的字节数,则应始终使用运算符。

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


7
@nevanking:在二进制补码机上(这是我所知道的每台机器...),是的。但是,C不能保证确实如此。
FatalError 2014年

@nevanking我对C完全陌生,但不是32767,因为否则它将使用另一位| byte?想象一下,我可以保留3位数字(0或1),所以我可以从000到111(十进制为7)。7在2的指数之前。如果我可以直到8(1000),那么我可以一直使用这4位数字直到15!32767等恰好在指数2之前,用尽了所有可用的字节。
RGS

3
@RSerrao我也不是C专家,但是AFAIK的正数比最大负数小1。所以-8到7,-256到255,依此类推。负数不必算零。
2014年

1
“ 16位。在这种情况下,int为2个字节”可能是错误的,如果CHAR_BIT为16,则sizeof(int)可以为1个字节(或char)。
12431234123412341234123

6
@nevanking:仅当您为signed假定为2的补码表示形式时int。C没有做这个假设。1的补码和符号幅度系统不能-32768用16位表示;相反,它们具有两个零表示(正数和负数)。这就是为什么的最小范围int[-32767..32767]
John Bode

33

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

背后的想法int是,它应该与给定平台上的自然“字”大小匹配:16位平台上的16位,32位平台上的32位,64位平台上的64位,您就明白了。但是,出于向后兼容的目的,某些编译器倾向于使用32位int甚至在64位平台上也位。

int除非您正在使用某些具有16位字长的嵌入式平台,否则2字节的时间已经过去了(16位平台?)。您的教科书可能很旧。


2
The idea behind int was that it was supposed to match the natural "word" size on the given platform-这就是我想要的。知道原因可能是什么?在自由世界中,int可以在内存中占据任意数量的连续字节吗?8,16,随便
bholagabbar

19

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

 [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

3
有人编辑了您的信息以“修正”范围,但是我不确定您的编辑是否充分反映了您的意图。它采用二进制补码实现,这在大多数情况下是正确的,但不是全部。由于您的回答特别指出了实现依赖性,因此我认为编辑可能是错误的。如果您同意,请确保恢复编辑。
科迪·格雷

1
@ k06a 您的编辑不正确。您已将原始范围专门更改为2补码范围-这些不是 C标准中指定的范围。
Antti Haapala '18

@CodyGray,它一直来回波动,过去3年一直是1的补码,OP没有说什么,所以我还原了一个编辑,将其更改为2的补码,并带有“修正范围”,因为它说“您可以可靠地假设” ,这仍然不完全正确。
Antti Haapala '18

13

C中的Integer变量占用2个字节还是4个字节?

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


它取决于哪些因素?

最好考虑范围,而不是大小。两种方法在实践中都会有所不同,尽管我们会看到,按范围选择变量类型比选择大小要容易得多。还需要注意的是,该标准鼓励我们考虑基于范围而不是大小来选择整数类型,但是现在让我们忽略标准做法,让我们好奇心探索sizeof,字节CHAR_BIT和整数表示...让我们深入研究一下兔子洞,亲眼看看...


sizeof,字节和 CHAR_BIT

以下声明取自C标准(链接至上文),以我认为无法改进的语言来描述。

sizeof操作者产生其操作数的大小(以字节为单位),其可以是表达或类型的括号名称。大小由操作数的类型确定。

假定您有一个清晰的认识,将导致我们对字节进行讨论。通常会假设一个字节为八位,而实际上却CHAR_BIT告诉您一个字节中有多少位。在谈论常见的两个(或四个)字节整数时,这只是细微差别中的另一个而已

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

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

因此,根据您的系统,它sizeof (unsigned int)可以是大于零的任何值(不只是2或4),就好像CHAR_BIT是16,则单个(十六位)字节中有足够的位来表示由十六进制描述的十六位整数。标准(如下所述)。那不一定是有用的信息,是吗?让我们深入研究...


整数表示

C标准规定的最小精度/范围所有标准整数类型(和CHAR_BIT,也FWIW)这里。由此,我们可以得出一个最小的需要多少位来存储的价值,但我们可能也只是选择根据我们的变量范围。但是,此答案所需的大部分细节都位于此处。例如,以下标准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)(即,对两字节和四字节整数的常见误解忽略了这些细节)。


13

C99 N1256标准草案

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

C 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的等级应大于long int的等级,后者应大于int的等级,后者应大于short int的等级,后者应大于有符号字符的等级。
  • 任何无符号整数类型的秩应等于相应的有符号整数类型的秩(如果有)。
  • 对于所有整数类型T1,T2和T3,如果T1的等级高于T2,并且T2的等级高于T3,则T1的等级高于T3

8

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

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


6

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位字节的Texas Instruments MCU的问题 C99,C11兼容编译器。

的TMS320C28x看来charshort并且int所有 16个位宽,因此一个字节。long int是2个字节,又long long int是4个字节。C的优点在于,仍然可以为这样的平台编写高效的程序,甚至可以以可移植的方式完成!


“因为CHAR_BIT是9!” -那时他们有362880位计算能力!?令人印象深刻。
乔什·戴斯蒙德

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,但不能更大不仅如此,长期以来也是如此。它还说,短期和长期的大小不能相同。


1
使用%dsize_t参数为UB。
Paul R

3

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

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


2
#include <stdio.h>

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

这将返回4,但可能取决于计算机。


1

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

C中的Integer变量占用2个字节还是4个字节?

C允许“字节”为每个“字节”以外的8位。

CHAR_BIT 不是位字段的最小对象的位数(字节)C11dr§5.2.4.2.11

大于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.11int INT_MAX

最小范围int力的比特大小为至少 16 -即使处理器是“8位”。在专用处理器中可以看到类似64位的大小。其他值(例如18、24、36等)已经出现在历史平台上,或者至少在理论上是可能的。现代编码很少担心非2的幂int位大小。

计算机的处理器和体系结构驱动着 int位大小的选择。

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


-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,在这里您可以对可变数组大小执行任何操作。


提供的链接是错误的信息来源,因为它假设情况并非总是正确的(例如char,始终如此signed
Andrei Damian-Fekete
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.