C语言中的"int"类型是2字节还是4字节?

在C语言中,整数变量占用2个字节还是4个字节取决于你所使用的平台以及编译器的配置。唯一权威的答案是使用sizeof运算符来查看在你特定情况下整数的大小。

“它取决于哪些因素?”

“范围”可能是最好考虑的,而不是“大小”。在实践中,两者都会变化,但选择变量类型时按范围选择比按大小选择更加可靠,正如我们将看到的那样。还要注意,标准鼓励我们根据“范围”而不是“大小”选择整数类型,但现在让我们“忽略标准惯例”,让我们的好奇心探索“sizeof”、字节和“CHAR_BIT”以及整数表示……让我们深入了解一下……

sizeof, bytes 和 CHAR_BIT

以下语句摘自C标准(上面已链接),我认为这些语言无法改进地描述了这个问题。

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

假设我们已经清楚地理解了这一点,那么我们将讨论关于 bytes 的内容。通常人们认为一个 byte 包含八位,实际上 CHAR_BIT 可以告诉你一个 byte 中包含多少位。这只是另一个在谈论 常见的二(或四)字节整数 时并未考虑到的微妙之处。

让我们总结一下:

sizeof => 字节大小,

CHAR_BIT => 每字节包含的位数。

因此,根据您的系统,sizeof (unsigned int) 可以是大于零的 任何 值(不仅仅是2或4),例如如果 CHAR_BIT 是16,则 一个单独的(十六位)字节 具有足够的位数来表示标准描述的十六位整数(如下所引用)。这并不一定是有用的信息,让我们深入探讨一下...

整数表示

C标准规定了所有标准整数类型(以及CHAR_BIT)的最小精度/范围这里。从中,我们可以推导出存储值所需的最小位数,但我们也可以根据范围选择变量。然而,这个答案所需的大部分细节都在此处。例如,下面的内容指出标准的unsigned int需要(至少)16位的存储空间:

UINT_MAX 65535 // 2¹⁶ - 1

因此,我们可以看到无符号整数需要(至少)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标准允许这种情况发生。一些机器(如this one)通过将两个较小的(有符号)整数值组合在一起来实现更大的整数类型......当组合有符号整数时,会浪费一个符号位。在C语言中,这个浪费的位被认为是填充位。其他填充位的例子可能包括奇偶校验位和陷阱位。

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