有趣的strcmp实现失败。(C)

有趣的strcmp实现失败。(C),c,pointers,character,strcmp,c-strings,C,Pointers,Character,Strcmp,C Strings,我正在做一个小项目,我无法访问任何C标准库(从头开始构建ARM结构的微核,甚至必须实现printf) 在这种情况下,我使用达夫的机器方法实现了strcmp 下面是完整的代码 int strcmp ( const char *str1, const char *str2 ) { while ( *str1 || *str2 ) if ( *(str1++) != *(str2++) ) return *str1 - *str2; return 0; } 这是有道理的;在

我正在做一个小项目,我无法访问任何C标准库(从头开始构建ARM结构的微核,甚至必须实现printf)

在这种情况下,我使用达夫的机器方法实现了strcmp

下面是完整的代码

int
strcmp ( const char *str1, const char *str2 )
{
   while ( *str1 || *str2 )
       if ( *(str1++) != *(str2++) ) return *str1 - *str2;
   return 0;
}
这是有道理的;在一段时间内,它似乎在测试用例上工作,直到终端系统发生故障。我追查到了这个strcmp

起初我认为它首先增加了str1,然后在str2增加之前与str2进行比较1。事实证明并非如此,但请任何人验证在某些情况下是否会发生这种情况?

然后我发现问题出在*str1-*str2中,所以将其更改为返回1。i、 e.生成的代码如下所示:

   while ( *str1 || *str2 )
       if ( *(str1++) != *(str2++) ) return 1;
   return 0;
虽然我想要的只是一个“equals”检查,所以更改为“1”没有问题,但我仍然想知道为什么原始代码失败了2。是否有人能就它如何失败给出一些提示或建议?我更希望strcmp遵循标准的C接口,即它返回一个非零值,以说明有关str1和str2的更多信息

测试用例为:

code_t // a function pointer type
program_find ( char *program )
{
if (strcmp( program, "exit" ) == 0) return ....
else if (strcmp( program, "k1" ) == 0) return ....
else if (strcmp( program, "k3" ) == 0) return ....
else if (strcmp( program, "perf" ) == 0) return ....
else if (strcmp( program, "test_libc" ) == 0) return ....
}
当*程序为“k3”时,它返回“k1”,“test_libc”返回“perf”

原来的问题是通过给它“return1”来解决的,所以这个问题纯粹是为了C的利益。
也欢迎提供建议或链接到strcmp文件。我已经看到了IEEE的规范接口

在进行比较时,您在str1和str2上使用了后期增量。这会导致它们在进行减法运算之前递增,因此减法的两个字符是错误的

更好的实施方式是

int
strcmp ( const char *str1, const char *str2 )
{
   while ( *str1 || *str2 ) {
       if ( *str1 != *str2 ) return *str1 - *str2;
       ++str1;
       ++str2;
   }
   return 0;
}

计算表达式:

*(str1++) != *(str2++)
将取消对指针的引用,比较结果,然后递增两个指针。当strcmp
strcmp
返回时,它们指向的是与您比较的内容不同的内容

请记住,实现
strcmp
始终返回1或0将使其无法对字符串列表进行排序!您需要返回-1/0/+1以使其可用。

您有两个问题:

int
strcmp ( const char *str1, const char *str2 )
{
    const unsigned char *s1 = (const unsigned char *)str1;
    const unsigned char *s2 = (const unsigned char *)str2;

    while (*s1 && *s1 == *s2) {
        s1++;
        s2++;
    }

    return *s1 - *s2;
}
  • 在对返回值执行减法运算之前,增加指针,因此返回值不正确
  • 特定于
    strcmp()
    的标准指示字符串的元素作为
    无符号字符进行比较
解决这些问题:

int
strcmp ( const char *str1, const char *str2 )
{
    const unsigned char *s1 = (const unsigned char *)str1;
    const unsigned char *s2 = (const unsigned char *)str2;

    while (*s1 && *s1 == *s2) {
        s1++;
        s2++;
    }

    return *s1 - *s2;
}

当字符串长度不等时会发生什么情况?假设字符串都以null结尾,因此将对其进行检查,因为您将在结尾处与null字符进行比较。check out,C99标准库从头开始的(不完整)实现;
string.h
中函数的实现可以在这里找到:啊,我明白了。这就是为什么*(str1++)!=*(++str2)尝试终究没有成功。您只需检查
*s1
*s2
中的任何一种是否为零,因为另一种情况将无法通过相等性检查;有关DevSolar的参考实现,请参阅