【问题标题】:Why use '\0' instead of 0 for memset?为什么在 memset 中使用 '\0' 而不是 0?
【发布时间】:2014-05-22 14:59:27
【问题描述】:

根据这个 Unix 文档http://pubs.opengroup.org/onlinepubs/009695399/functions/bzero.html

The memset() function is preferred over bzero().

For maximum portability, it is recommended to replace 
the function call to bzero() as follows:

#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)


但是void *memset(void *s, int c, size_t n); 第二个参数是 int 那么为什么他们推荐 '\0' 而不是 0? memset() 文档说“memset() 函数应将 c (转换为无符号字符) arg 复制到第一个 s 指向的对象的 strong>n 个字节。"这是更有效还是更明确?这里是否涉及最佳实践?

【问题讨论】:

标签: c++ c


【解决方案1】:

第二个 arg 是一个 int 那么为什么他们推荐 '\0' 而不是 0?

为了清楚起见,这个东西最终会变成一个 NUL 字符;毕竟memset 会将其转换为unsigned char。这只是风格问题,因为'\0' 的类型为int,因此与0 相同。

【讨论】:

  • 在 C++ 中,任何 符合 的编译器,无论是否正常,都会在编译时将 '\0' 转换为 0。在 C 中,不会发生转换,因为 '\0' 已经是 int 类型。
  • c 中的字符文字无论如何都是整数,而不是字符。 stackoverflow.com/questions/433895/…
  • 该问题同时标记为 C 和 C++。在 C 中,'\0' 的类型为 int。在 C++ 中,它的类型为 char。 (无论哪种情况,将'\0' 作为memset 的第二个参数传递都是完全正确的。)
【解决方案2】:

效率更高吗?

在某种程度上:bzero 从未真正成为标准的一部分。这就是为什么您链接到的页面建议使用memset。因此,使用memset 更有效,因为您可以放心,您的代码可以在所有标准 C 编译器上编译。

'\0' 而不是 0
该标准要求 char 可以安全地转换为 int:

基本源和基本执行字符集都应具有以下内容 成员:
[...]
十进制数字
0 1 2 3 4 5 6 7 8 9
[...]
在源和执行基本字符集中, 上述十进制数字列表中 0 之后的每个字符的值应大于 1 前一个的值。

所以将 '\0' 传递给 int 参数不是问题。更重要的是:您正在传递一个 zero-escape-sequence,这实际上与传递 0 相同。
然而,它更明确:memset 会将 N 个字节初始化为您传递给它的任何值。 C 中唯一保证为 1 且只有 1 个字节大的类型是 char 类型。

所以:

memset(some_ptr, 0, 12);
//is, in practice identical to:
memset(some_ptr, '\0', 12);

但是当您设置 12 个字节时,传递一个 1-byte-big 类型的值可以更好地反映这一点。出于这个原因,我更喜欢显式传递一个字符,但这取决于你。

memset 的历史:
memset 功能已经存在很长时间了。事实上,它早在函数原型时代就已经存在了!

要记住的另一件事是,C 中的字符文字本身与大多数文字值一样,是整数。

【讨论】:

  • +1 以获得完整答案;不清楚“它早在函数原型时代就存在”的措辞。
  • \0 不是数字,因此您的报价无关紧要。
  • “在某种程度上:bzero 从来都不是标准的一部分。” “在某种程度上”是什么意思? bzero 从来不是任何官方 C 或 C++ 标准的一部分;这是明确的。
  • @KeithThompson: bzero 由 POSIX 标准化。
  • @larsmans:其实不是。 bzero 已被 POSIX.1-2001 弃用并标记为 LEGACY,并被 POSIX-1.2008 完全删除。您提出了一个很好的观点,它a 标准指定,但至少根据我的经验,“标准”一词通常指的是 ANSI 或 ISO 语言标准。
猜你喜欢
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-28
  • 2018-08-16
  • 1970-01-01
相关资源
最近更新 更多