我知道比较“字符串”的正确方法在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 正确打印 1 ,表示它们不相等。但有人可以向我解释为什么在比较字符数组时, == 返回 0

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

有帮助吗?

解决方案

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

即。 “安德烈亚斯”在前两行代码中存储了可执行数据。 C标准说这些字符串是常量的,因此将两个指针指向同一个存储区。

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

其他提示

呃......当 == 打印1时,表示 相等。它与strcmp不同,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("%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

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

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

s3 == s4 也是如此。这就是“阵列衰变成指针”。在工作。

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

0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */

从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指向相同的静态内存块,但我不希望这种行为是可移植的。

您无法比较字符串,但可以比较指针。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top