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

问题描述 投票:0回答:4

这个问题在这里已有答案:

我刚刚创建了这个函数,通过减去它们的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*的整数值也不同 注意到这些整数取决于在代码中首先声明哪个变量,但是如果它们具有相同的字符串,这使得该函数完美地工作,那么它是相同的整数,那么它取决于编译器吗?

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

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

c++ c
4个回答
8
投票

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


5
投票

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

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

还有来自standard: -

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

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

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


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
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.