【问题标题】:How to do reverse memcmp?如何做反向memcmp?
【发布时间】:2012-01-14 10:09:23
【问题描述】:

如何进行反向内存比较?如,我给出了两个序列的结尾,我希望指针在开始时递减,而不是在结束时递增。

【问题讨论】:

  • @VladLazarenko 尽管这是关于比较而不是复制,但我想答案是相同的 - 因此这可以被视为欺骗。
  • 我实际上犯了一个小错误,我收回我的投票,对不起大家

标签: c memcmp


【解决方案1】:

C 标准库中没有内置函数可以做到这一点。下面是一个自己滚动的简单方法:

int memrcmp(const void *s1, const void *s2, size_t n)
{
    if(n == 0)
        return 0;

    // Grab pointers to the end and walk backwards
    const unsigned char *p1 = (const unsigned char*)s1 + n - 1;
    const unsigned char *p2 = (const unsigned char*)s2 + n - 1;

    while(n > 0)
    {
        // If the current characters differ, return an appropriately signed
        // value; otherwise, keep searching backwards
        if(*p1 != *p2)
            return *p1 - *p2;
        p1--;
        p2--;
        n--;
    }

    return 0;
}

如果你有高性能的东西,你应该一次比较 4 字节的字而不是单个字节,因为内存延迟将是瓶颈;但是,该解决方案要复杂得多,并不值得。

【讨论】:

  • 应该是 const unsigned char p1 = (const unsigned char)s1 + n - 1; const unsigned char p2 = (const unsigned char)s2 + n - 1;例如考虑 n=1。
  • 如果有人出于速度方面的考虑想要反转 memcmp - 上述循环可能只会对 large 数组更快,因为优化的机器指令可能会导致未反转的 memcmp提供。另见:stackoverflow.com/a/21106815/7015849
【解决方案2】:

很像最初由 Vlad Lazarenko 链接的帖子 (C memcpy in reverse),这里有一个基于此的解决方案,我尚未测试,但应该可以帮助您开始。

int reverse_memcmp(const void *s1, const void *s2, size_t n)
{
    unsigned char *a, *b;
    a = s1;
    b = s2;
    size_t i = 0;

    // subtracting i from last position and comparing
    for (i = 0; i < n; i++) {
        if (a[n-1-i] != b[n-1-i]) {
            // return differences between different byte, strcmp()-style
            return (a[n-1-i] - b[n-1-i]);
        }
    }

    return 0;
}

【讨论】:

  • 这不会编译 -- void* 指针不能被取消引用。您应该在取消引用之前转换为 unsigned char*
【解决方案3】:

您需要做的就是指定两端和要比较的大小以及步长。请特别注意,步长可能是获得预期结果的最重要部分。如果您限制大小,它将大大简化实施。对于 char 的大小,您可以执行以下操作:

int compare (void *one, void *two, size_t size)
  {
  char *one_char = (char *)one;
  char *two_char = (char *)two;
  size_t i;

  for (i = 0; i < size; i++)
    {
    if (*(one_char - i) != *(two_char - i))
       return(NOT_EQUAL);
    }  

  return(EQUAL);
  }

【讨论】:

    【解决方案4】:

    更短的代码(C 代码不需要强制指针类型转换):

    int reverse_memcmp(const void *end1, const void *end2, size_t n) {
        const unsigned char *a = end1, *b = end2;
        for (; n; --n)
            if (*--a != *--b) return *a - *b;
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      • 1970-01-01
      • 2016-06-11
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      相关资源
      最近更新 更多