【问题标题】:memcmp C implementation - any logical errors with this onememcmp C 实现 - 这个有任何逻辑错误
【发布时间】:2009-05-01 15:43:06
【问题描述】:

memcmp C 实现 - 这个有任何逻辑错误吗?

我正在寻找memcmp()的实现,我找到了这个代码sn-p,但它清楚地标明了代码sn-p存在1个逻辑错误。你能帮我找出逻辑错误吗?

基本上,我用不同的输入针对 memcmp() 的 string.h 库实现测试了这段代码,但预期的输出始终与函数的库版本相同。

这里是sn-p的代码:

#include <stdio.h>
#include <string.h>

int memcmp_test(const char *cs, const char *ct, size_t n)
{
  size_t i;   

  for (i = 0; i < n; i++, cs++, ct++)
  {
    if (*cs < *ct)
    {
      return -1;
    }
    else if (*cs > *ct)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
} 



int main()
{
    int ret_val = 20; //initialize with non-zero value 

    char *string1 = "china";
    char *string2 = "korea";

    ret_val = memcmp_test(string1,string2,5); 

    printf ("ret_val is = %d",ret_val);

    getchar();
    return 0;
}

我用两个示例字符串运行程序,程序将在比较两个字符串的第一个字符后返回。在上述情况下,ret_val 为 -1。

上面的代码sn-p应该符合的memcmp()的定义是:

'C'库函数memcmp的定义是 int memcmp(const char *cs, const char *ct, size_t n)

比较cs的前n个字符和ct的前n个字符。 如果 cs ct,则返回 > 0。 如果 cs == ct,则返回 0。

肯定有LOGICAL错误,你能帮我找出来吗?

【问题讨论】:

  • 这是作业吗?我只想说看看'return 0'的情况,想想它在什么时候做了什么。
  • 还请注意 mehrdad 的回答。或做 (unsigned char)*cs
  • hmm,虽然我认为即使 (unsigned char)*cs -1) 会高于 0x82 (=> -2)。但实际上当解释为无符号字符时,0x81 当然小于 0x82。所以我想正确/便携的唯一方法可能是按照 mehrdad 显示或执行 (unsigned char)cs (unsigned char)ct 。那是一只狡猾的野兽!
  • @JohannesSchaub-litb:或者更明显的是,比较 +0 和 -0 相等:)

标签: c


【解决方案1】:

正如现在所写的那样,这段代码只会测试输入的第一个字节。 else return 0 需要移出循环,在最后留下return 0

  for (i = 0; i < n; i++, cs++, ct++)
  {
    if (*cs < *ct)
    {
      return -1;
    }
    else if (*cs > *ct)
    {
      return 1;
    }
  }
  return 0;
 } 

【讨论】:

    【解决方案2】:

    我猜因为char 签名是实现定义的,你可以比较unsigned

    int memcmp_test(const char *cs_in, const char *ct_in, size_t n)
    {
      size_t i;  
      const unsigned char * cs = (const unsigned char*) cs_in;
      const unsigned char * ct = (const unsigned char*) ct_in;
    
      for (i = 0; i < n; i++, cs++, ct++)
      {
        if (*cs < *ct)
        {
          return -1;
        }
        else if (*cs > *ct)
        {
          return 1;
        }
      }
      return 0;
    } 
    

    【讨论】:

    • @litb:谢谢,我认为它也可以在没有强制转换的情况下编译(可能会发出警告)。您是这里的 C/C++ 权威。随意;)
    • +1 用于注意到细微的问题:memcmp() 应该进行无符号比较!另外,我认为 if (*cs - *ct) { return *cs - *ct; } 是安全的,因为提升为int,假设int 保证至少有一个额外的位。
    【解决方案3】:

    看看你的 for 循环。它只检查一个字符。

    【讨论】:

      【解决方案4】:

      严格来说签名是错误的。 correct 一个是:

      int memcmp(const void *s1, const void *s2, size_t n);
      

      您的代码比较 ck 并发现 c 小于 k 尽职尽责地返回 -1。但是,如果这两个相等,您会得到一个不正确的结果,因为您要提前返回。

      如果您阅读文档,您会发现:

      非零返回值的符号应由被比较对象中不同的第一对字节(均解释为类型无符号字符)的值之间的差异符号确定

      这基本上意味着您通过返回保留 ('c' - 'k') 符号的内容来做正确的事情。

      更简单的实现可以在here找到。

      【讨论】:

        【解决方案5】:

        返回0;仅在比较第一个字符后发生。它应该放在循环之外。

        【讨论】:

          【解决方案6】:

          这个 sn-p 非常适合我!!

          #include <stdio.h>
          #include <string.h>
          
          int memcmp_test(const char *cs, const char *ct, size_t n)
          {
           size_t i;   
          
           for (i = 0; i < n; i++, cs++, ct++)
           {
          if (*cs < *ct)
          {
            return -1;
          }
          else if (*cs > *ct)
          {
            return 1;
          }
          }
          
            return 0;  
            } 
          int main()
          {
          int ret_val = 20; //initialize with non-zero value 
          const char *string1 = "DWgaOtP12df0";
          const char *string2 = "DWGAOTP12DF0";
          ret_val = memcmp_test(string1,string2,5);
          printf ("ret_val is = %d",ret_val);
          getchar();
          return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-14
            • 1970-01-01
            • 2011-06-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多