【问题标题】:Why does memcmp() return 256 for a difference of 1? [duplicate]为什么 memcmp() 返回 256 的差值为 1? [复制]
【发布时间】:2016-05-12 15:27:35
【问题描述】:

所以我必须使用 C 重新创建 memcmp() 函数,并且我的函数按预期工作。它返回两个字符串中不匹配的第一个字符的差异。

我的功能:

int ft_memcmp(const void *s1, const void *s2, size_t n)
{
    unsigned char   *ptr1;
    unsigned char   *ptr2;

    ptr1 = (unsigned char *)s1;
    ptr2 = (unsigned char *)s2;
    while (n && (*ptr1 == *ptr2))
    {
        ptr1++;
        ptr2++;
        n--;
    }
    if (n == 0)
        return (0);
    else
        return (*ptr1 - *ptr2);
}

我的主要:

int main(void)
{
    const char  *s1 = "acc";
    const char  *s2 = "abc";
    int         res;

    res = memcmp(s1, s2, 3); 
    printf("%i\n", res);

    return (0);
}

所以这个main会返回256,但是如果你使用我的函数(ft_memcmp)你得到1。显然区别是1而不是256,但是为什么原来的函数返回256?差为 2,我得到 512...

【问题讨论】:

  • 注意:return 是一个语句,而不是一个函数。您使用的括号是表达式的一部分,而不是语句的一部分。声明不需要它们。不建议将它们用于简单的表达,因为它们会使阅读变得复杂。
  • 好的,公平的评论。我完全同意。然而,我的大学使用了一种叫做“规范”的东西,它要求我们在使用“返回”时加上括号,以及关键字和括号之间的空格。例如,'while ()' 而不是 'while()'....
  • @Olaf 这是您的个人意见。让我们在这里关注问题的技术方面,即使您很少会看到 return (0),我同意它应该读为 return 0,很明显。
  • *ptr1 - *ptr2 将在使用相同大小的unsigned charunsigned 的平台(例如某些图形处理器)上提供错误的符号答案,因为数学溢出。 (*ptr1 > *ptr2) - (*ptr1 < *ptr2) 是一个惯用的替代品..
  • *ptr1 - *ptr2 和(保持指针不变,但增加索引)ptr1[some_int] - ptr2[some_int] 是相同的。所以不要认为这是对(*ptr1 > *ptr2) - (*ptr1 < *ptr2)的改进。

标签: c linux macos unix


【解决方案1】:

为什么 memcmp() 为 1 的差返回 256?

首先,正如@where_is_tftp 的回答,memcmp() 唯一需要返回的是0,比较时一些正数和一些负数.

256 而不是 1 - 肯定是因为优化。

一个好的memcmp() 尽可能利用比char 更宽的类型进行比较。

示例:在考虑对齐和总长度后,第一次比较(使用 32 位 unsigned)发现差异不是在 1 的位置(位 0),而是在 256 的位置(位 8)。由于返回 256 与 1 一样有效,因此无需简化。请记住,memcmp() 是特定于平台的,它的实现可以做 C 代码不能做的事情——比如安全地访问数组之外​​。其他细节在此省略。

    byte 3         2        1        0
    don't care    'c'      'c'      'a'
  - don't care    'c'      'b'      'a'
    -----------------------------------
  = don't care     0        1        0
  &    0          0xFF     0xFF     0xFF
    -----------------------------------
  =    0           0        1        0   --> 256

【讨论】:

    【解决方案2】:

    我在 memcmp 的符号旁边找不到关于非零返回值的确切值的声明(在手册页或 Open Group 页面上):

    非零返回值的符号应由 第一对字节的值之间的差异(两者 解释为类型 unsigned char) 的对象不同 比较。

    返回值

    memcmp() 函数应返回一个大于的整数,等于或小于0,如果s1指向的对象大于,等于 分别小于或等于 s2 所指向的对象。

    这里没有说是字符之间的小数差异。

    【讨论】:

    • “第一对字节的值之间的差异......在被比较的对象中不同。”它指出“值之间的差异”。如果不是小数/整数,我还能如何找到差异?
    • @Kbam7 可能是hamming distance,或者Levenshtein distance
    • @Kbam7: 1) C 没有“十进制”变量。难怪,因为该语言依赖于二进制计算机。十进制只是输入/输出表示。 char 和 realted 也是整数类型。
    • 是的,我知道 char 和相关类型源于整数。即'a' == 97。但是现在,谁能告诉我为什么我在Linux上使用memcmp时得到'256'?为什么我的朋友在他的 Mac 上使用 memcmp 时会得到“1”?我们都使用相同的代码,但得到不同的答案?
    • @Kbam7 "如果不使用小数/整数,我还能如何找到差异?" --> 使用compare
    猜你喜欢
    • 2019-04-28
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 2012-06-08
    相关资源
    最近更新 更多