C语言字符串比较:使用等号进行比较

7

我有这段代码:

char *name = "George"

if(name == "George")
   printf("It's George")

我曾认为c字符串不能用==符号进行比较,而是必须使用strcmp函数。但不知何故,在使用gcc(版本4.7.3)编译时,这段代码可以正常工作。我认为这是错误的,因为它就像比较指针一样,所以我在谷歌上搜索了很多人都说这是错误的,不能用==进行比较。那么为什么这种比较方法可以正常工作呢?


7
使用 strcmp() 函数时,你正在比较地址。 - Grijesh Chauhan
1
@nouney UB是什么?我看不出有任何理由需要它。 - user529758
2
针对楼主:请查看此代码,它将向您展示为什么它能够工作。 - nouney
@GrijeshChauhan 嗯,我不明白你想向我解释什么。 - nouney
@nouney 我不小心打错了 - Grijesh Chauhan
显示剩余2条评论
5个回答

28
我曾认为C字符串不能用==符号进行比较,必须使用strcmp函数。

没错。

我认为这是错误的,因为这就像比较指针一样,所以我在谷歌上搜索了很多人都说这是错误的,不能用==进行比较。

也没错。

那么为什么这种比较方法有效呢?

它并不“有效”。它只是看起来“有效”而已。

这种情况发生的原因可能是编译器优化:两个字符串字面值相同,因此编译器实际上只生成一个实例,并且在引用字符串字面值时始终使用同一个指针/数组。


10

仅提供参考,以下是 @H2CO3 的回答:

C11 6.4.5 字符串字面量

未指定这些数组是否不同,只要它们的元素具有适当的值即可。如果程序尝试修改此类数组,则行为是未定义的。

这意味着在您的示例中,name(一个字符串字面量 "George")和 "George" 可能共享同一位置,也可能不共享,这取决于实现。因此不要指望这一点,在其他机器上可能会产生不同的结果。


1
+1,GCC会将所有字符串字面量放在.rodata节中,并且足够聪明以消除重复。 :) - ludesign

5
您所做的比较是比较两个字符串的位置,而不是它们的内容。恰好您的编译器决定只创建一个包含字符"George"的字符串字面量。这意味着存储在name中的字符串和第二个"George"的位置相同,因此比较返回非零值。
然而,编译器并不需要这样做-它也可以轻松地创建两个不同的字符串字面量,位置不同但内容相同,然后比较将返回零。

1
这将失败,因为您正在比较两个不同字符串的两个不同指针。 如果此代码仍然有效,则是GCC的重度优化结果,它仅保留一个副本以进行大小优化。
使用strcmp()链接

3
OP刚刚说字符串相等了,并知道为什么应该使用strcmp()。这不是一个答案,也是错误的,因为“你正在比较两个不同指针所指的两个单独的字符串”是不正确的 - 就像我在我的答案中解释的那样。 - user529758
1
字符串相等,但它们位于两个不同的内存位置。因此它们的指针是不同的,比较是错误的。如果这段代码仍然有效,则这是GCC的重度优化结果。 - Andrejs Cainikovs
“但它们被放置在两个不同的内存位置” - 不,它们并没有,我建议你最终“阅读”我的答案。 - user529758
1
@AndrejsCainikovs,由于它们是不可变的,因此它们可以放置在一个地址中。 - awesoon

-1

如果您比较两个字符串,那么您比较的是这些字符串的基地址而不是其中的实际字符。要比较字符串,请使用strcmp()strcasecmp()库函数或编写类似于以下代码的程序。下面的代码只是字符串比较所需的逻辑部分,不是完整代码。

void mystrcmp(const char *source,char *dest)
{
    for(i=0;source[i] != '\0';i++)
        dest[i] = source[i];
   dest[i] = 0;

}

这对我更像是一个 mtystrcpy - alex01011

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接