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

时间:2012-07-11 18:11:57

标签: c int byte

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

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

13 个答案:

答案 0 :(得分:152)

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

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

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

答案 1 :(得分:93)

这是C中可能会引起混淆的一个点,但C标准仅为保证支持的整数类型指定最小范围int保证能够保持-32767到32767,这需要16位。在这种情况下,int是2个字节。但是,实现可以自由地超出最小值,因为您会看到许多现代编译器使int 32位(这也意味着4个字节非常普遍)。

你的书说2个字节的原因很可能是因为它已经过时了。有一段时间,这是常态。一般情况下,如果您需要查看正在使用的平台上有多少字节,则应始终使用sizeof运算符。

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

答案 2 :(得分:29)

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

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

2字节int的时间早已消失(16位平台?),除非您使用的是一些16位字大小的嵌入式平台。你的教科书可能很旧。

答案 3 :(得分:18)

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

 [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

答案 4 :(得分:11)

  

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

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


  

它取决于哪些因素?

可能最好考虑

范围,而不是 size 。两者在实践中都会有所不同,尽管按范围而不是大小选择变量类型会更加万无一失,我们将会看到。同样重要的是要注意标准鼓励我们考虑选择基于范围而不是 size 的整数类型,但是现在让我们< em>忽略标准练习,让我们的好奇心探索sizeof,字节和CHAR_BIT,以及整数表示......让我们挖掘兔子洞并看到它我们自己...


sizeof,字节和CHAR_BIT

以下陈述取自C标准(与上述相关),用我认为无法改进的词语来描述。

  

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

假设清楚的理解将引导我们讨论 bytes 。通常假设字节是8位,实际上是CHAR_BIT tells you how many bits are in a byte。这只是在讨论常见的两个(或四个)字节整数时未考虑的另一个细微差别。

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

  • sizeof =&gt;大小(以字节为单位)和
  • CHAR_BIT =&gt;字节数

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


整数表示

C标准规定了所有标准整数类型的最小精度/范围(以及CHAR_BIT,fwiw)here。由此,我们可以导出最小,以确定存储所需的位数,但我们也可以根据范围选择我们的变量。尽管如此,这个答案所需的大部分细节都存在于此。例如,以下标准unsigned int需要(至少)16位存储:

UINT_MAX                                65535 // 2¹⁶ - 1

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

  

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

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

值位是常见的误解似乎在计算。上面的示例使用unsigned整数类型,它通常只包含值位,因此很容易错过细节中的恶魔。

签名位 ...在上面的示例中,我引用UINT_MAX作为unsigned int的上限,因为它是提取值的一个简单示例{ {1}}来自评论。对于签名类型,为了区分正值和负值(符号),我们还需要包含符号位。

16

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


正如您所看到的,标准似乎鼓励在选择整数类型时考虑INT_MIN -32768 // -(2¹⁵) INT_MAX +32767 // 2¹⁵ - 1 .. INT_MINother minimum/maximum values from the standard等范围,并且不鼓励依赖大小,因为还有其他微妙的因素可能被遗忘,例如INT_MAX和填充位可能会影响CHAR_BIT的值(即两字节和四字节整数的常见误解< / em>忽略了这些细节。)

答案 5 :(得分:10)

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),具有较小整数转换等级的类型的值范围是a   另一种类型的值的子范围。

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

  

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

     
      
  • long long int的等级应大于long int的等级,即   应大于int的等级,其应大于short的等级   int,应大于signed char的等级。
  •   
  • 任何无符号整数类型的等级应等于相应的等级   有符号整数类型,如果有的话。
  •   
  • 对于所有整数类型T1,T2和T3,如果T1的等级大于T2且T2具有   比T3更高的排名,那么T1的排名高于T3
  •   

答案 6 :(得分:6)

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

int可能是16到64位宽,具体取决于平台。

答案 7 :(得分:5)

主要取决于您使用的平台。它取决于编译器到编译器。目前大多数编译器中 int 4字节。 如果要检查编译器使用的内容,可以使用sizeof(int)

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

c编译器唯一承诺的是short的大小必须等于或小于int,long的大小必须等于或大于int.So如果int的大小是4,那么short的大小可以是2或4但不大于那个。对于long和int来说,这是真的。它还说短和长的大小不能相同。

答案 8 :(得分:4)

  

C的大小是2字节还是4字节?

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

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

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

对于范围为至少CHAR_BIT 的平台,

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


尽管36位计算机大部分已死,但仍有平台具有非8位字节。就在昨天,有a question about a Texas Instruments MCU with 16-bit bytes,它具有C99和C11兼容的编译器。

TMS320C28x上,CHAR_BITcharshort看来都是16位宽,因此一个字节。 int是2个字节,long int是4个字节。 C的美丽之处在于,人们仍然可以为这样的平台编写高效的程序,甚至可以以可移植的方式完成它!

答案 9 :(得分:3)

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

如果您想确保使用特定尺寸的类型,请使用<stdint.h>

中的类型

答案 10 :(得分:2)

#include <stdio.h>

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

这会返回4,但它可能与机器有关。

答案 11 :(得分:1)

  

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

     

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

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

  
    

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

  

超过8的值越来越少见。为了获得最大的可移植性,请使用CHAR_BIT而不是8.C中int的大小为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的对象的最小值     类型int INT_MAX +32767的对象的最大值     C11dr§5.2.4.2.11

  

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

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

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

答案 12 :(得分:0)

This is a good source for answering this question.

但是这个问题总是真实的答案是“是的。两个。”

这取决于您的架构。如果你要在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)并定义function2(数组t,int size_of_t)。调用“function(t)”通过一些复制工作来测量长度,并将结果发送到function2,在那里你可以对变量数组大小做任何你想做的事情。