==
不是我们比较两个数组的方式,因为那只会比较地址:
#include <iostream>
int main()
{
char a[] = "aaa";
char b[] = "aaa";
if (a == b)
std::cout << "Yes" << std::endl;
else
std::cout << "No" << std::endl;
return 0;
}
这段代码甚至给了我一个警告:
Array comparison always evaluates to false
但是当我尝试这样做时:
if ("aaa" == "aaa")
它似乎工作正常。仍然给我一个警告,但警告是:
Condition is always true
起初,我认为这是某种缓存的东西,所以我尝试了一个相当不寻常的字符串文字:
if ("whuiwhqohqweihqweohi" == "whuiwhqohqweihqweohi")
在 MSVC 和 g++ 上仍然可以正常工作。那是一种依赖于实现的行为吗?我知道比较在编译时已知的变量不是很有用,但我的问题只是“为什么会这样?”。
此外,使用 auto
似乎也有效:
#include <iostream>
int main()
{
auto a = "whuiwhqohqweihqweohi";
auto b = "whuiwhqohqweihqweohi";
if (a == b) {
std::cout << "Yes" << std::endl;
}
else {
std::cout << "No" << std::endl;
}
return 0;
}
这段代码产生了正确的输出。这里的a
和b
是什么类型?
请不要回答“使用 std::string”。与我的问题无关
最佳答案
在这里您必须非常小心,因为您正在查看的某些情况与其他情况并不完全相同。
在你的第一个例子中:
char a[] = "aaa";
char b[] = "aaa";
if (a == b)
您正在创建两个 arrays char,每个都是从字符串文字初始化的。然后您将尝试将这些数组相互比较。在大多数情况下(包括本例),数组名称的计算结果为该数组中第一个元素的地址。所以你实际上是在比较两个数组的地址。它们不可能相同,因此比较肯定会产生 false
。
在您的第二个示例中:if ("aaa"== "aaa")
,您比较的是字符串文字本身,而不是从字符串初始化的数组文字。
标准不保证此结果。该标准允许(但不要求)将相同的字符串文字合并在一起。然而,您真正比较的不是文字的内容——而是它们存储的地址。如果编译器合并字符串文字,使它们位于同一地址,这将产生 true
。如果它让它们分开,它将产生 false
。
在您的auto
案例中:
auto a = "whuiwhqohqweihqweohi";
auto b = "whuiwhqohqweihqweohi";
您遇到的情况几乎相同——a
和 b
最终都作为指向 char 的指针,保存字符串文字的地址。如果编译器合并这些文字,它们将指向同一个地址,因此它们比较相等。如果编译器不将它们合并在一起,每个都有自己的地址,并且它们将比较为不相等。
这里的要点是,这些都不是比较字符串的内容,只是比较它们的存储地址。内容仅在两个字符串文字具有(或至少以)相同内容时才能合并的程度。
就“至少结束”而言,我指的是编译器如果你有类似的东西:“wing”
在一个地方和“swing”
在另一种情况下,编译器可以自由合并两者,因此代码如下:
auto a = "wing";
auto b = "swing";
...编译器可以将 swing
存储在一个地方,并初始化 a
以指向该存储文字的第二个字符。
关于C++ 字符串文字相等性检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53965165/