为什么“==”运算符适用于这两个 C 字符串?

Why the "==" operator works on these two C strings?

我多次读到 == 运算符不适用于 C 字符串。 但我对这个示例感到困惑,感谢 Coliru 网站进行了测试。

#include <stdio.h>

typedef struct S {
    const char *data;
} S;

const char *Text = "hello";

void test()
{
    n = { "hello" };
    printf("%d\n", n.data == Text);
}

int main(void) 
{
    test();
    return 0;
}

如果您更改值的任何字母(Textn),结果为 0,如果完全相同,则结果为 1.

如果 == 不适用于字符串,在这种情况下此运算符会给出意想不到的结果 ?

本次调用的结果

printf("%d\n", n.data == Text);

实现已定义。此调用可以输出 10。比较了两个指向相同字符串文字(相同文字的第一个字符)的指针(它们的值)。结果取决于编译器选项,即编译器是将相同的字符串文字存储为不同的数组还是一个数组(具有静态存储持续时间)。

来自 C 标准(6.4.5 字符串文字)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

要比较字符串,您应该使用标准 C 字符串函数 strcmp

== 运算符,以及关系比较运算符 <<=>>=,当应用于指针类型时,比较指针值,而不是指向的对象。

因此,当且仅当 ab 指向同一个对象时,a == b 将计算为 1

在您的示例中,Textn.data 使用两个相同的字符串文字 "hello" 进行了初始化。这些字符串文字是编译为 2 个不同的对象还是编译为单个对象由实现定义。

在您的系统上,编译器生成相同的对象,因此两个指针指向相同的对象,因此是相同的。

尝试使用此代码验证 == 不适合比较字符串:

#include <stdio.h>
#include <string.h>

typedef struct S {
    const char *data;
} S;

int main(void) {
    char copy[] = "hello";
    const char *Text = "hello";
    S n = { "hello" };

    printf("pointer comparison: %d, string comparison: %d\n",
           n.data == Text, strcmp(n.data, Text) == 0);

    printf("pointer comparison: %d, string comparison: %d\n",
           n.data == copy, strcmp(n.data, copy) == 0);

    return 0;
}

输出:

pointer comparison: 1, string comparison: 1
pointer comparison: 0, string comparison: 1