[在采访中问我这个问题,在某些操作系统中,char
的大小为2字节,但是在某些操作系统中,其为4字节或不同。
为什么会这样?
为什么与其他基本类型(例如int
)不同?
这可能是一个技巧问题。 sizeof(char)
是总是 1。
如果大小不同,可能是由于编译器不合格,在这种情况下,问题应该是关于编译器本身,而不是关于C或C ++语言。
1 sizeof运算符得出对象中的字节数 其操作数的表示形式。操作数可以是一个表达式, 未评估的值,或带括号的type-id。的大小 运算符不得应用于具有功能或 不完整类型,或在所有其枚举数之前变为枚举类型 已声明,或以此类括号的名称,或 指定位字段的左值。
sizeof(char)
,sizeof(signed char)
和sizeof(unsigned char)
为1。将sizeof应用于任何其他基本类型(3.9.1)的结果为 实现定义的。(重点是我的]
所指出类型以外的其他类型的大小是实现定义的,并且由于各种原因而有所不同。如果int
用64位而不是32位表示,则具有更好的范围,但在32位体系结构上,它以32位表示的效率更高。
类型的物理大小(以位数为单位)通常由目标硬件决定。
例如,某些CPU只能以不小于16位的单位访问内存。为了获得最佳性能,可以将char
定义为16位整数。如果要在此CPU上使用8位字符,则编译器必须生成额外的代码,以便将8位值打包和拆包到16位存储单元中。多余的打包/解压缩代码会使您的代码变大和变慢。
这还没有结束。如果将16位存储单元细分为8位字符,则可以有效地在地址/指针中引入额外的位。如果CPU中的普通地址是16位,那么您将多余的第17位放在哪里?有两个选项:
后一种选择有时可能很实用。例如,如果整个地址空间分成两半,其中一个由内核使用,另一半由用户应用程序使用,则应用程序指针将永远不会在其地址中使用一位。您可以使用该位在16位存储单元中选择8位字节。
C旨在在尽可能多的不同CPU上运行。这就是为什么char
,short
,int
,long
,long long
,void*
,void(*)()
,float
,double
,long double
,wchar_t
的物理尺寸的原因,等等可能有所不同。
现在,当我们在讨论为同一CPU生成代码的不同编译器中的不同物理尺寸时,这将成为更多选择。但是,它可能看起来并不那么随意。例如,许多Windows编译器都定义int
=long
= 32位。他们这样做是为了避免程序员在使用Windows API时感到困惑,因为Windows API期望INT
=LONG
= 32位。由于缺少程序员的注意力,将int
和long
定义为其他名称会导致bug。因此,在这种情况下,编译器必须紧随其后。
最后,C(和C ++)标准与chars
和bytes
一起使用。它们在大小上是相同的概念。但是C的字节不是您通常的8位字节,从法律上讲,它们可以比前面解释的大。为避免混淆,可以使用术语octet
,其名称表示数字8。为此,许多协议都使用该词。
感谢Alexey Frunze,这是我正在寻找的答案。我在安德鲁·tenenbawn操作系统书的硕士期间研究了这个概念]