Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用返回String1-String2==0进行相等性检查是否安全?_C++_C_C11 - Fatal编程技术网

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

C++ 使用返回String1-String2==0进行相等性检查是否安全?,c++,c,c11,C++,C,C11,我刚刚创建了这个函数,通过减去两个字符串的整数值来检查它们之间的相等性 int EQ(const char* CString1, const char* CString2) { return CString1 - CString2 == 0; } 但是,我不确定这是否是检查char*字符串的安全方法 它不适用于数组,因为它们有不同的整数,所以我为此创建了其他函数 int EQA(const char* CString1, const char* CString2){ if(CS

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

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*
时,为什么我要在
EQ()上使用
EQA()
strcmp()

第一个EQ()比我以前使用的任何其他标准函数都要,因此我非常喜欢使用它

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

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

编辑:一些答案侧重于调试我的第二个示例,而不是回答我的问题,因此我对其进行了编辑。

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

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指针之前访问内存。还考虑如果CSTRIGN2为NULL?

怎么办? 当(i>0&&--i)
检查位置0时,您确定这是
?我想它会说“你好”和“果冻”是一样的。。。(已确认。未检查位置0)

来自(来自C标准-N1570)

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

以及来自:-

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

考虑到标准的这一部分,这是不正确的。(您不能确保它们指向相同的位置或相同数组的不同位置,如上所述),当代码不符合上述标准时,您可以在代码上使用它们


此外,您不能检查两个字符串(中以nul结尾的
char
数组)减去其地址后的相等性-它如何检查地址中内容的相等性?不可能。Standard没有免费提供strcmp
——在这种情况下,您可以使用它来比较字符串的内容

两个按字典顺序相等的字符串并不意味着它们存储在同一个内存位置。减去它们的地址进行比较可能会得到一些错误的结果。如果两个指针不指向同一数组的元素或一个指针不指向数组最后一个元素,则指针减法没有意义。

我建议使用标准函数
strcmp
进行词典字符串比较

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

只是一个旁注:如果
CString1
的长度为0或1,则没有UB。@Johanneschaub litb.:如果允许减去不一定指向同一数组的两个不同地址-减去地址并得出其内容相同的结论是不好的-这是胡说八道。顺便说一下,这些函数只是为了学习,谢谢你的回答:)@KiraSama.:你必须用strcmp来写一个法律代码——这就是我的观点。我希望你明白我在回答中所说的,你工作太辛苦了,strcmp就是你所需要的。你的两个功能都被窃听了
EQA
检查
CString1
是否是
CString2
的前缀,因此
EQA(“,“hello”)
是正确的。作为学习练习,可以尝试重写标准函数,但这不是在实际代码中要做的事情。我尝试检查strlen()在EQA发布之前,我将其删除,以便于澄清@约翰,这不是我的原创作品,但你是对的,因为我不会在真正的代码中使用它们,我正在尝试理解它们是如何工作的。请不要滥用
排版
@Tas不,这不安全。将两个不指向同一数组的指针相减是一种未定义的行为。我将我的问题编辑到我的原始函数中,首先使用strlen(),你是对的,我忘记了
NULL
的事情,我很感激指出这一点是的,我现在明白了,谢谢你和所有在这里努力回答我问题的人,我很感激他们所有的+1,但我必须选择一个简单的答案,指向实际问题,你直接检查等式是对的,我做了一个多么无用的函数^^这并不一定是无用的:两个对象可能是“同卵双胞胎”,但我们有兴趣知道它们是相同的(比如:在同一时间占据同一位置),还是只是彼此的副本。这只是一个不同的问题:-)Re“在测试中看起来会不同”:这不是保证