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

时间:2018-12-28 22:54:17

标签: 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;
}

此代码甚至给我一个警告:

  

数组比较的总结果为false

但是当我尝试这样做时:

if ("aaa" == "aaa")

似乎工作正常。仍然给我一个警告,但警告是:

  

条件永远是真的

起初,我认为这是某种缓存内容,所以我尝试了一种非常不寻常的字符串文字:

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”。这和我的问题无关

3 个答案:

答案 0 :(得分:7)

在这里您必须非常小心,因为您正在寻找的某些情况与其他情况并不完全相同。

在您的第一个示例中:

char a[] = "aaa";
char b[] = "aaa";

if (a == b)

您正在创建两个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指向存储的文字的第二个字符。

答案 1 :(得分:6)

对于

char a[] = "aaa";
char b[] = "aaa";

您比较本地阵列的地址 ab,因此不能有相同的地址。

对于

if ("aaa" == "aaa")

您比较2个可能相同或不同的静态char指针。

来自string_literal

  

允许(但不是必需)编译器组合存储以相等或重叠的字符串文字。这意味着,当通过指针进行比较时,相同的字符串文字可能会比较相等,也可能不会相等。

bool b = "bar" == 3+"foobar" // could be true or false, implementation-defined

在相同情况下:

auto a = "whuiwhqohqweihqweohi";
auto b = "whuiwhqohqweihqweohi";

autoconst char*

答案 2 :(得分:3)

这两个文字字符串是常量,编译器可能会用一个实例替换您在代码中拥有的两个实例,然后将其替换为true。

auto abchar const*