C中的整数变量是占用2字节还是4字节?它取决于哪些因素?
大多数教科书都说整数变量占用 2 个字节。但是当我运行一个打印整数数组的连续地址的程序时,它显示的差异为 4。
我知道它等于sizeof(int)
。an 的大小int
实际上取决于编译器。过去,当处理器是 16 位时,anint
是 2 个字节。如今,在 32 位和 64 位系统上它通常是 4 个字节。
尽管如此,使用sizeof(int)
是获取执行程序的特定系统的整数大小的最佳方法。
编辑:int
修复了大多数 64 位系统上 8 个字节的错误语句。例如,在 64 位 GCC 上是 4 个字节。
这是 C 语言中一开始可能令人困惑的一点,但 C 语言标准仅指定了保证支持的整数类型的最小范围。int
保证能够保持-32767到32767,这需要16位。在这种情况下,int
, 是 2 个字节。但是,实现可以自由地超出该最小值,因为您会看到许多现代编译器都生成int
32 位(这也意味着 4 字节非常普遍)。
你的书说 2 个字节的原因很可能是因为它太旧了。一度,这是常态。一般来说,sizeof
如果您需要了解它在您正在使用的平台上的字节数,您应该始终使用该运算符。
为了解决这个问题,C99 添加了新类型,您可以在其中显式请求特定大小的整数,例如int16_t
or int32_t
。在此之前,没有通用的方法来获取特定宽度的整数(尽管大多数平台在每个平台的基础上都提供了类似的类型)。
没有具体的答案。这取决于平台。它是实现定义的。它可以是 2、4 或其他。
背后的想法int
是它应该与给定平台上的自然“字”大小相匹配:16 位平台上的 16 位,32 位平台上的 32 位,64 位平台上的 64 位,你明白了。但是,出于向后兼容的目的,一些编译器更喜欢坚持使用 32 位int
,即使在 64 位平台上也是如此。
2 字节的时代int
已经一去不复返了(16 位平台?),除非您使用的是具有 16 位字长的嵌入式平台。你的教科书可能很旧了。
这个问题的答案取决于您使用的平台。
但无论平台如何,您都可以可靠地假设以下类型:
[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
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
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_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)
(即对两字节和四字节整数的常见误解忽略了这些细节)。
唯一的保证是char
必须至少8 位宽,short
并且int
必须至少16 位宽,并且long
必须至少32 位宽,并且sizeof (char)
<= sizeof (short)
<= sizeof (int)
<= sizeof (long)
(对于这些类型的无符号版本也是如此)。
int
根据平台的不同,宽度可能在 16 到 64 位之间。
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 语言的美妙之处在于,仍然可以为这样的平台编写高效的程序,甚至可以以可移植的方式完成!
大多数情况下,它取决于您使用的平台。它取决于编译器到编译器。现在在大多数编译器中,int是4 个字节。如果你想检查你的编译器正在使用什么,你可以使用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 也是如此。它还说短和长的大小不能相同。
这取决于实现,但通常在 x86 和其他流行的架构(如 ARM )上int
占用 4 个字节。您始终可以在编译时使用sizeof(int)
或您想要检查的任何其他类型进行检查。
如果要确保使用特定大小的类型,请使用<stdint.h>
#include <stdio.h>
int main(void) {
printf("size of int: %d", (int)sizeof(int));
return 0;
}
这将返回 4,但它可能取决于机器。
C“int”的大小是 2 字节还是 4 字节?
C中的整数变量是占用2字节还是4字节?
C 允许“字节”不是每个“字节”8 位。
CHAR_BIT
不是位域(字节)的最小对象的位数 C11dr §5.2.4.2.1 1
大于 8 的值越来越少见。为了获得最大的可移植性,请使用CHAR_BIT
而不是 8。C 中int
in位的大小 为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 次方位大小。int
int
计算机的处理器和架构驱动int
位大小的选择。
然而,即使使用 64 位处理器,int
出于兼容性原因,编译器的大小也可能是 32 位,因为大型代码库取决于int
32 位(或 32/16)。
但这个问题是一种永远真实的回答“是的。两者兼而有之。”
这取决于您的架构。如果您要在 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,在那里你可以对可变数组大小做任何你想做的事情。