【问题标题】:fwrite portabilityfwrite 可移植性
【发布时间】:2012-07-27 09:38:23
【问题描述】:

fwrite 是可移植的吗?我并没有真正面临下面描述的问题,但我想了解 C 的基础知识。

免得假设我们有两台机器 A8(字节 = 8 位)和 B16(字节 = 16 位)。

下面的代码会在两台机器上产生相同的输出吗?

unsigned char[10] chars;
...
fwrite(chars,sizeof(unsigned char),10,mystream);

我猜 A8 将产生 80 位(10 个八位字节),而 B16 将产生 160 位(20 个八位字节)。 我错了吗?

如果仅使用 uintN_t 类型,则不会出现此问题,因为它们的位长度与字节大小无关。但也许 uint8_t 在 B16 上不存在。

这个问题的解决方案是什么?

我猜想构建一个 uint32_t 数组,将我的字节放入这个数组中(根据机器的架构使用智能移位和掩码)并编写这个数组将解决问题。但这并不令人满意。再次假设 uint32_t 存在于所有平台上。这个数组的填充将非常依赖于当前机器的架构。

感谢您的回复。

【问题讨论】:

  • "但 B16 上可能不存在 uint8_t。"不能,除了位域之外,没有任何东西可以小于char
  • sizeof(char)总是 1.
  • "我猜 A8 会产生 80 个八位字节,B16 会产生 160 个八位字节。我错了吗?"是的,这将是80个。 160 bits 或 10 resp。 20 八位字节.
  • 简答:代码可以移植,生成的数据不能移植。一台机器可以有任何字长、CHAR_BIT 或字节序。网络人员使用“八位字节”一词来确保他们假设 8 位字节。碰巧具有不同 CHAR_BIT 值的实现(对于 TCP/IP)应该表现“AS-IF”。
  • @mvera - char 没有字节序,它只有一个“端”。

标签: c


【解决方案1】:

fwrite() 是一个标准库函数。所以它必须对每个 C 编译器都是可移植的。 也就是说,它必须在该编译器的 C 标准库中定义才能支持您的机器。

所以8位、16位、32位的机器给你同样的高级操作。

但如果你想设计那些库函数,那么你必须考虑机器架构,该机器的内存组织。

作为 C 编译器用户,您不应该为内部行为而烦恼。

我想你只是想使用那些 C 库函数。因此,不同机器的功能行为没有差异。

【讨论】:

    【解决方案2】:

    几乎每台现代计算机上的一个字节都是 8 位。但是fwrite 不可移植还有另一个原因:
    小端机器上写的文件,大端机器等读不出来。

    【讨论】:

    • 错了,在C语言中,一个字节总是CHAR_BIT位。您拥有的唯一保证是它至少 8.
    • 这仅适用于跨越多个内存单元的类型,例如16 位/32 位/64 位整数类型或浮点数。在 BE 和 LE 机器上,字符数组(本质上是字符串)总是以完全相同的方式在内存和磁盘上布局。
    【解决方案3】:

    在 C 中,char 被定义为“机器的最小可寻址单元”。即char不一定是8位。

    在大多数情况下,依靠 char 是 8 位这一事实是足够安全的,而不是处理一些极端情况。

    一般来说,您可能无法将“半个字节”写入存储中的文件。此外,设计用于不同字节大小机器的设备之间的硬件级别的可移植性也会存在问题。如果您正在处理其他设备(例如电信或其他设备),则必须实现比特流。

    【讨论】:

      猜你喜欢
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多