C++ 字符串文字相等性检查?

标签 c++ arrays compare string-literals

== 不是我们比较两个数组的方式,因为那只会比较地址:

#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;
}

这段代码产生了正确的输出。这里的ab是什么类型?

请不要回答“使用 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";

您遇到的情况几乎相同——ab 最终都作为指向 char 的指针,保存字符串文字的地址。如果编译器合并这些文字,它们将指向同一个地址,因此它们比较相等。如果编译器不将它们合并在一起,每个都有自己的地址,并且它们将比较为不相等。

这里的要点是,这些都不是比较字符串的内容,只是比较它们的存储地址。内容仅在两个字符串文字具有(或至少以)相同内容时才能合并的程度。

就“至少结束”而言,我指的是编译器如果你有类似的东西:“wing”在一个地方和“swing” 在另一种情况下,编译器可以自由合并两者,因此代码如下:

auto a = "wing";
auto b = "swing";

...编译器可以将 swing 存储在一个地方,并初始化 a 以指向该存储文字的第二个字符。

关于C++ 字符串文字相等性检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53965165/

相关文章:

c++ - 对于使用 Clang 构建的目标文件,我需要与 MinGW 链接哪些库?

javascript - 如何从 JavaScript 中的对象内部解构数组?

c# - 协调 2 个长度不同的数组 c#

C - 比较 float 和 if 语句

python - SCons - 为 CUDA、CORBA 等集成自定义构建器

c++ - 通过函数指针间接完美转发?

java - 比较不同对象的 2 个 Java 数组列表,并将匹配的行添加到新列表中

具有计算值和数字范围的 awk 过滤列 |更新

c++ - 如何将字符串从 C# 传递到 C++ 并指定编码

c - 在函数中交换两个数组的指针