在一次采访中向我提出了这个问题,在某些操作系统中大小char
为 2 字节,但在某些操作系统中为 4 字节或不同。
为什么呢?
为什么它与其他基本类型不同,例如int
?
在一次采访中向我提出了这个问题,在某些操作系统中大小char
为 2 字节,但在某些操作系统中为 4 字节或不同。
为什么呢?
为什么它与其他基本类型不同,例如int
?
这可能是一个棘手的问题。sizeof(char)
始终为1。
如果大小不同,可能是因为编译器不符合标准,在这种情况下,问题应该是编译器本身,而不是 C 或 C++ 语言。
1 sizeof 运算符产生其操作数的对象表示中的字节数。操作数要么是一个不求值的表达式,要么是一个带括号的类型 ID。sizeof 运算符不得应用于具有函数或不完整类型的表达式,或应用于所有枚举数都已声明之前的枚举类型,或应用于此类类型的括号名称,或应用于指定位域的左值。
sizeof(char)
,sizeof(signed char)
并且sizeof(unsigned char)
是 1。 sizeof 应用于任何其他基本类型(3.9.1)的结果是实现定义的。(强调我的)
除了指出的类型之外,其他类型的 sizeof 是实现定义的,并且由于各种原因而有所不同。如果 Anint
以 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 时产生混淆,这些 API 需要INT
= LONG
= 32 位。由于失去程序员的注意力,定义int
和long
作为其他东西会导致错误。因此,在这种情况下,编译器必须效仿。
最后,C(和 C++)标准使用chars
and操作bytes
。它们在尺寸方面是相同的概念。但是 C 的字节不是典型的 8 位字节,它们可以合法地比前面解释的要大。为避免混淆,您可以使用术语octet
,其名称暗示数字 8。许多协议为此目的使用该词。