C中的Integer变量是占用2个字节还是4个字节?它取决于哪些因素?
大多数教科书都说整数变量占用2个字节。 但是当我运行一个程序打印一个整数数组的连续地址时,它显示了4的差异。
答案 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_t
或int32_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_MIN
和other 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位宽,short
和int
必须至少 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_BIT
,char
和short
看来都是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,在那里你可以对变量数组大小做任何你想做的事情。