为啥在 memset 中使用 '\0' 而不是 0?
Posted
技术标签:
【中文标题】为啥在 memset 中使用 \'\\0\' 而不是 0?【英文标题】: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 中,'\0'
是一个 int
。但是,您使用哪个并不重要。
我没有答案,但我不得不说我也想知道这个。就我个人而言,我会尽量明确。 (我不知道转换 0
-> '\0'
可能出现任何问题)
@KasiyA '\0'
不是char
。这是一个int
。
'\0'
和 0
都是同一个常量。使用是一种风格选择。如果memset()
的目标是char *
,IMO,'\0'
传达更多含义。否则使用0
。
Nips,只看了10秒左右,这个问题有大约一百万个骗子:***.com/questions/5919735/…***.com/questions/781668/char-to-int-conversion-in-c***.com/questions/17096990/why-use-bzero-over-memset
【参考方案1】:
第二个 arg 是一个 int 那么为什么他们推荐 '\0' 而不是 0?
为了清楚起见,这个东西最终会变成一个 NUL 字符;毕竟memset
会将其转换为unsigned char
。这只是风格问题,因为'\0'
的类型为int
,因此与0
相同。
【讨论】:
在 C++ 中,任何 符合 的编译器,无论是否正常,都会在编译时将'\0'
转换为 0
。在 C 中,不会发生转换,因为 '\0'
已经是 int
类型。
c 中的字符文字无论如何都是整数,而不是字符。 ***.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 语言标准。
以上是关于为啥在 memset 中使用 '\0' 而不是 0?的主要内容,如果未能解决你的问题,请参考以下文章
使用 memset 初始化整数数组而不是像 array[10]=0 这样的默认零初始化是不是有任何性能优势?