【问题标题】:Why do the sizes of data types change as the Operating System changes?为什么数据类型的大小会随着操作系统的变化而变化?
【发布时间】:2012-09-22 07:54:16
【问题描述】:

在一次采访中问我这个问题,char 的大小在某些操作系统中是 2 字节,但在某些操作系统中是 4 字节或不同。

为什么会这样?

为什么它不同于其他基本类型,例如int

【问题讨论】:

  • 那是完全错误的。在 C++ 中(我也相信 C),char 的大小总是 1 字节。
  • @KonradRudolph:不过,C++ 字节不一定与平台字节相同。想想 36 位平台,它将一个平台字节分成两个或三个或四个 C 字节(每个 18/12/9 位)。
  • 或者他们希望你说,“一个字节与八位字节不同”,或者说,“你的意思是 intwchar_t 大小不同,而不是比char?.
  • "为什么它不同于其他基本类型,例如 int?"不是,一个 int 也可以有许多不同的大小。

标签: c++ c operating-system size


【解决方案1】:

这可能是一个棘手的问题。 sizeof(char)总是 1。

如果大小不同,可能是因为编译器不符合标准,在这种情况下,问题应该是编译器本身,而不是 C 或 C++ 语言。

5.3.3 Sizeof [expr.sizeof]

1 sizeof 运算符产生对象中的字节数 其操作数的表示。操作数要么是表达式,要么 未评估,或带括号的类型 ID。的大小 运算符不应应用于具有函数或 不完整的类型,或在其所有枚举数之前的枚举类型 已声明,或此类类型的括号名称,或 一个指定位域的左值。 sizeof(char)sizeof(signed char)sizeof(unsigned char) 为 1。 sizeof 应用于任何其他基本类型 (3.9.1) 的结果是 实现定义。(强调我的)

指出的其他类型的 sizeof 是实现定义的,并且由于各种原因而有所不同。如果int 以 64 位而不是 32 位表示,则它的范围更好,但在 32 位架构上,它也更有效地作为 32 位。

【讨论】:

  • 它不仅仅是char.. 任何数据类型。假设int 在 windows 中有 2 个字节,但在 linux 中有 4 个字节。
  • @SachinMhetre 你问过char。对于int,情况就不同了。
  • 那为什么 int 不一样??
  • 机器中“字符”的大小可能(并且通常是)2(或更多)字节。但是,正如答案所说,C++ 表达式sizeof(char) 将始终产生 1。感到困惑?阅读:parashift.com/c++-faq/sizeof-char.html
【解决方案2】:

类型的物理大小(以位数表示)通常由目标硬件决定。

例如,某些 CPU 只能以不小于 16 位的单位访问内存。为获得最佳性能,char 可以定义为 16 位整数。如果你想在这个 CPU 上使用 8 位字符,编译器必须生成额外的代码,用于将 8 位值打包和解包到 16 位内存单元中。额外的打包/解包代码会使你的代码变得更大更慢。

这还没有结束。如果将 16 位存储单元细分为 8 位字符,则有效地在地址/指针中引入了一个额外位。如果 CPU 中的普通地址是 16 位的,那么你把这个额外的第 17 位放在哪里?有两种选择:

  • 使指针变大(32 位,其中 15 个未使用)并浪费内存并进一步降低速度
  • 将可寻址地址空间范围缩小一半,浪费内存,损失速度

后一种选择有时很实用。例如,如果整个地址空间被分成两半,其中一个由内核使用,另一个由用户应用程序使用,那么应用程序指针将永远不会使用其地址中的一位。您可以使用该位在 16 位存储单元中选择一个 8 位字节。

C 被设计为在尽可能多的不同 CPU 上运行。这就是为什么charshortintlonglong longvoid*void(*)()floatdouble、@98765433@2@4 的物理尺寸等可能会有所不同。

现在,当我们讨论在不同编译器中为同一 CPU 生成代码时的不同物理尺寸时,这更像是一种任意选择。然而,它可能并不像看起来那么随意。例如,许多 Windows 编译器定义 int = long = 32 位。他们这样做是为了避免程序员在使用 Windows API 时产生混淆,这些 API 需要 INT = LONG = 32 位。将intlong 定义为其他内容会由于程序员的注意力丢失而导致错误。因此,在这种情况下,编译器必须效仿。

最后,C(和 C++)标准使用 charsbytes。它们在尺寸方面是相同的概念。但是 C 的字节不是典型的 8 位字节,它们可以合法地比前面解释的要大。为避免混淆,您可以使用术语 octet,其名称暗示数字 8。许多协议为此目的使用该词。

【讨论】:

    猜你喜欢
    • 2021-08-22
    • 1970-01-01
    • 2018-09-15
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多