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

Ayx*_*xan 4 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;
}
Run Code Online (Sandbox Code Playgroud)

这段代码甚至给了我一个警告:

数组比较始终计算为false

但是当我尝试这个时:

if ("aaa" == "aaa")
Run Code Online (Sandbox Code Playgroud)

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

条件总是如此

起初,我认为它是某种缓存的东西,所以我尝试了一个相当不寻常的字符串文字:

if ("whuiwhqohqweihqweohi" == "whuiwhqohqweihqweohi")
Run Code Online (Sandbox Code Playgroud)

在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;
}
Run Code Online (Sandbox Code Playgroud)

此代码生成正确的输出.什么类型ab在这里?

请不要回答"使用std :: string".这与我的问题无关

Jer*_*fin 8

你必须在这里非常小心,因为你所看到的一些案例并不完全等同于其他案例.

在你的第一个例子中:

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

if (a == b)
Run Code Online (Sandbox Code Playgroud)

您正在创建两个char 数组,每个数组都是从字符串文字初始化的.然后,您尝试将这些阵列相互比较.在大多数情况下(包括这一个),数组的名称将计算为该数组中第一个元素的地址.所以你真的要比较两个数组的地址.那些不一样,所以比较保证会产生false.

在第二个示例中:if ("aaa" == "aaa")您正在比较字符串文字本身,而不是从字符串文字初始化的数组.

标准不保证结果.该标准允许(但不要求)将相同的字符串文字合并在一起.然而,你真正比较的不是文字的内容 - 它是存储它们的地址.如果编译器合并了字符串文字,那么它们就在同一个地址,这就会产生true.如果让它们分开,它就会产生false.

在你的auto情况下:

auto a = "whuiwhqohqweihqweohi";
auto b = "whuiwhqohqweihqweohi";
Run Code Online (Sandbox Code Playgroud)

你有几乎相同的situation-- ab双方最终为指针为char,拿着字符串文字的地址.如果编译器合并这些文字,它们都会指向相同的地址,因此它们将比较相等.如果编译器没有将它们合并在一起,则每个都将拥有自己的地址,并且它们将比较为不相等.

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

至于"至少结束",我指的是编译器,如果你有类似的东西:"wing"在一个地方和"swing"另一个地方,编译器可以自由地合并这两个,所以代码类似于:

auto a = "wing";
auto b = "swing";
Run Code Online (Sandbox Code Playgroud)

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


Jar*_*d42 6

对于

char a[] = "aaa";
char b[] = "aaa";
Run Code Online (Sandbox Code Playgroud)

你比较本地的地址阵列 ab,所以不能有相同的地址.

对于

if ("aaa" == "aaa")
Run Code Online (Sandbox Code Playgroud)

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

来自string_literal

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

bool b = "bar" == 3+"foobar" // could be true or false, implementation-defined
Run Code Online (Sandbox Code Playgroud)

在同样的情况下:

auto a = "whuiwhqohqweihqweohi";
auto b = "whuiwhqohqweihqweohi";
Run Code Online (Sandbox Code Playgroud)

autoconst char*.