【问题标题】:Why does wmemcpy exist when memcpy should suffice?当 memcpy 应该足够时,为什么 wmemcpy 存在?
【发布时间】:2016-07-28 23:56:34
【问题描述】:

wmemcpy 似乎执行与memcpy 相同的操作,但接受wchar_t* 而不是void*。如果这两个代码 sn-ps 应该具有相同的行为,它的存在如何证明?它有什么有用的用途吗?

memcpy(dest, wchar_array, sizeof(wchar_array));

wmemcpy(dest, wchar_array, sizeof(wchar_array) / sizeof(wchar_t));

【问题讨论】:

  • 一个弱的原因可能是当你有一个wchar_t 的数组时,wmemcpy 可能更有效,因为它可以假设合适的对齐方式。
  • @Lashane:术语“Word”不是“2 bytes”的同义词。正如“1 字节”而不是 8 位一样。
  • @Lashane:在没有必要的情况下使用错误的术语几乎没有用处。 “八位字节”这个词只需再输入一个字母。并且声明“word == 2 bytes”只是一个坏主意(您显然注意到了自己)。 “我知道这一点”——问题是大多数初学者都读到这一点,他们认为这样的陈述是普遍有效的。只需查看此处的问题,其中包含由于用户对尺寸做出错误假设而导致的错误。
  • @JordanMelo 我从来没有听说过 wmemcpy,直到你刚刚问到它。我同意它的存在似乎没有道理。我,我永远不会使用它。
  • @Olaf 您正在与“字节”进行一场失败的战斗。这是一个具有多种含义的词(就像“黑客”)。对于至少 99% 的发言者来说,通常使用“字节”表示“8 位”。

标签: c memcpy


【解决方案1】:

除了 davmac 关于 API 对称性和数组大小并不总是被授予的答案之外,应该强调的是,wmemcpy 的第三个参数是指要复制的元素数(而不是字节数)。

如果您使用wchar_t 对象并使用<wchar.h> 中的其他函数处理它们,这可能会方便一些事情。例如,wcslenwchar_t 元素的形式返回 C 宽字符串长度,wcschrwcsrchr 返回 wchar_t *,因此使用它们进行一些指针运算也使您处于数字的“领域”元素。

附:如果在您的示例中给出了最小 wchar_t 数组的大小,则使用 wmemcpy 可能会产生比您使用的 sizeof(wchar_array) 更优雅的代码:

#define SIZE 40
wchar_t wchar_array[SIZE];
// ...
wmemcpy(dest, wchar_array, SIZE);

【讨论】:

    【解决方案2】:

    我猜这主要是关于 API 对称性,而且,它允许更轻松地编写可以处理宽字符和普通字符串的代码(由预处理器定义或类似的切换)。

    本质上,如果您希望您的代码与char 一起使用,您可以将#define 复制功能作为memcpy。对于wchar_t,您将其定义为wmemcpy。您的 size 参数只是字符数(charwchar_t);请记住,参数不一定是固定大小的数组,因此使用sizeof 并不总是一种选择。

    例如,Win32 API 使用了类似的策略:如果您定义 UNICODE 预处理器符号,大多数函数会解析为它们的宽字符版本(后缀为 W),否则它们会解析为“窄”字符版本(以A为后缀); TCHAR 相应地定义为 charwchar_t;等等。结果是您可以相当轻松地编写适用于宽字符或常规字符的代码。

    当然,这绝不是必要的;但是,标准 C 库不一定应该是绝对最小的。你可能会争辩说calloc 是多余的,因为你总是可以使用malloc 然后memset,例如;但是它仍然存在。

    【讨论】:

    • 我不确定这是否有意义,因为我经常需要memcpy 整数或浮点数之类的东西。为什么没有imemcpy()fmemcpy()?为什么wchar_t 有自己的功能? memcpy 的工作基础是 char 是一个单字节,而不是一个字符;不过wchar_t 没有那个特殊属性。
    • @Cornstalks 但整数和浮点数不(通常)用于保存字符。 chartwchar_t 都是;它们之间的区别主要是它们的宽度/范围。因此,您可能希望编写与其中任何一个(或至少可以切换为支持其中一个)一起工作的代码是有道理的。
    • 我想我想说的是我不认为memcpy 是针对字符/字符串的。如果是这样,我希望它采用char* 而不是void*
    • @Cornstalks 它不是 geared 用于字符串,但您仍然可以使用它来复制字符串;您可以毫无问题地将其传递给char *。我并不是建议通常应该这样做,但它可以做到,而且可能已经做到了。
    • 我可以轻松地将#define 我的复制功能复制到类似#define copy(dest,src,size) memcpy(dest,src,(size)*2) 而不是wmemcpy(dest,src,size)wchar_t 并获得相同的效果。这是一个相当微不足道的转变。但这很好地说明了为什么有人可能想要它。
    猜你喜欢
    • 2017-05-26
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2023-04-02
    • 2021-09-14
    相关资源
    最近更新 更多