使用返回String1 - String2 == 0进行相等性检查是否安全?

时间:2018-03-01 06:22:28

标签: c++ c

我刚刚创建了这个函数,通过减去它们的Integer值来检查两个字符串之间的相等性

int EQ(const char* CString1, const char* CString2)
{
    return CString1 - CString2 == 0;
}

但是,我不确定这是否是检查char*字符串的安全方法

它不能使用数组,因为它们有不同的整数,所以我为此创建了其他功能

int EQA(const char* CString1, const char* CString2){
    if(CString1 == NULL || CString2 == NULL)
        return 0;
    int i = strlen(CString1);
    if(i != strlen(CString2))
        return 0;
    while(i>=0){
        if(CString1[i] != CString2[i])
            return 0;
        --i;
    }
    return 1;
}
  

我没有尝试过多地优化我的第二个功能

但在查看char*时,为什么我会使用EQA()strcmp()而不是EQ()

第一个 EQ()比我之前使用的任何其他标准功能更快所以我真的喜欢使用它

我在其他机器上测试了它工作,但char* 的整数值不同,也是 注意到这些整数取决于代码中哪个变量首先声明,但如果它们具有相同字符串,则它是相同的整数这使得这个功能完美无缺,那么 依赖 编译器

为什么不同的整数?,它仍然安全吗?

编辑:有些答案专注于调试我的第二个示例,而不是回答我的问题,所以我编辑了它。

4 个答案:

答案 0 :(得分:8)

两个按字典顺序排列的字符串并不意味着它们存储在同一个内存位置。减去他们的地址以进行比较可能会产生一些错误的结果。如果两个指针不指向同一个数组的元素或者指向数组最后一个元素的指针,则指针减法是没有意义的。
我建议使用标准函数strcmp进行字典字符串比较。

答案 1 :(得分:5)

没有

您可以在内存中的两个不同位置拥有相同字符串的两个副本,但您的方法会说它们不同。

char *s1 = "Hello";
char *s2 = strdup(s1);
printf("%d\n", strcmp(s1, s2)); /* prints 0 */
printf("%d\n", s1-s2); /* does not print 0 */

此外,您的EQA函数非常错误:EQA("Hello", "h")将在CString2指针之前访问内存。还要考虑一下如果CString2为NULL?

你确定while(i>0 && --i)检查位置0吗?我想它会说“Hello”和“Jello”是相同的......(确认。位置0未检查)

答案 2 :(得分:5)

来自6.5.6p9(来自C标准 - N1570

  

当减去两个指针时,都指向同一个数组对象的元素,或者指向数组对象的最后一个元素; 结果是两个数组的下标的差异元素。结果的大小是实现定义的,其类型(有符号整数类型)是标头中定义的ptrdiff_t。

还来自standard: -

  

...如果表达式PQ分别指向同一数组对象x[i]的元素x[j]x,则表达式P - Q具有价值   i−j;否则,行为未定义。

根据标准的这一部分,这是不正确的。(你不能确保它们指向上面提到的相同阵列的相同位置或不同位置)当你的代码没有&#39时你的代码就是undefined behavior ; t遵循上述标准。

此外,您无法检查两个字符串(中的nul终止char数组)减去其地址的相等性 - 如何检查地址中的内容是否相等?它不可能。标准没有提供strcmp什么都没有 - 在这种情况下你可以用它来比较字符串的内容。

答案 3 :(得分:2)

不要检查差异是否为0,只需检查它们是否相等。它会给你相同的结果,但是它不会告诉你字符串是否不同但只有你的字符串存储在同一个地方(两个相同的字符串可以存储在不同的地方和与你的测试看起来会有所不同。)