4

我知道在 C 中比较“字符串”的正确方法是使用strcmp,但现在我尝试将一些字符数组与==运算符进行比较,得到了一些奇怪的结果。

看看下面的代码:

int main()
{
    char *s1 = "Andreas";
    char *s2 = "Andreas";

    char s3[] = "Andreas";
    char s4[] = "Andreas";

    char *s5 = "Hello";

    printf("%d\n", s1 == s2); //1
    printf("%d\n", s3 == s4); //0
    printf("%d\n", s1 == s5); //0
}

第一个printf正确打印 a 1,这表明它们不相等。但是有人可以向我解释为什么在比较字符数组时==返回 a0吗?

有人可以向我解释为什么第一个printf返回 a 1(即它们相等)并且字符数组返回 a0吗?

4

7 回答 7

20

== 是比较内存地址。
您的编译器可能使 s1 和 s2 指向相同的静态数据以节省空间。

IE。前两行代码中的“Andreas”存储在您的可执行数据中。C 标准说这些字符串是常量,因此优化了两个指针以指向同一个存储。

char[] 行通过将数据复制到变量中来创建变量,因此在执行期间存储在堆栈上的不同地址。

于 2009-11-26T00:09:20.647 回答
4

呃......当==打印一个 1 时,这意味着它们相等的。它与 strcmp 不同,后者返回字符串的相对顺序。

于 2009-11-26T00:10:51.347 回答
2

您正在比较地址而不是字符串。前两个是不变的,只会被创建一次。

int main()
{
    char *s1 = "Andreas";
    char *s2 = "Andreas";

    char s3[] = "Andreas";
    char s4[] = "Andreas";

    char *s5 = "Hello";

    printf("%d\n", s1 == s2); //1
    printf("%p == %p\n", s1, s2);
    printf("%d\n", s3 == s4); //0
    printf("%p != %p\n", s3, s4);
    printf("%d\n", s1 == s5); //0
    printf("%p != %p\n", s1, s5);
}

在我的电脑上输出,但你明白了:

1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0
于 2009-11-26T00:15:09.880 回答
1

稍等... 1 表示真,0 表示假。所以你的解释是部分倒退的。至于为什么前两个字符串似乎相等:编译器只构建了该常量字符串(s1/2)一次。

于 2009-11-26T00:12:41.723 回答
1

s1 == s2表示“ (char*) == (char*)”或地址相同。

同样的事情s3 == s4。这就是“数组衰减成指针”在起作用。

你有比较错误的结果的含义:

0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */
于 2009-11-26T00:16:39.113 回答
1

从 s1 到 s5 的所有值都不是char本身,它们是指向char 指针。所以你要比较的是每个字符串的内存地址,而不是字符串本身。

如果您这样显示地址,您可以看到比较运算符实际在做什么:

#include <stdio.h>

int main() {
  char *s1 = "Andreas";
  char *s2 = "Andreas";

  char s3[] = "Andreas";
  char s4[] = "Andreas";

  char *s5 = "Hello";

  printf("%p\n", s1); // 0x80484d0
  printf("%p\n", s2); // 0x80484d0
  printf("%p\n", s3); // 0xbfef9280
  printf("%p\n", s4); // 0xbfef9278
  printf("%p\n", s5); // 0x80484d8
}

字符串在内存中的确切分配位置是特定于实现的。在这种情况下, s1 和 s2 指向同一个静态内存块,但我不希望这种行为是可移植的。

于 2009-11-26T00:22:19.273 回答
0

你不能比较字符串,但你可以比较指针。

于 2009-11-26T00:13:37.643 回答