C ++字符串文字相等性检查? [英] C++ string literal equality check?

查看:87
本文介绍了C ++字符串文字相等性检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

== is not how we compare two arrays, since that would only compare the addresses:

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

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

This code even gives me a warning:


数组比较总是计算为假

Array comparison always evaluates to false

但是当我尝试这样做时:

But when I tried this:

if ("aaa" == "aaa")

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

It seemed to be working fine. Still gives me a warning, but the warning is:


条件始终为真

Condition is always true

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

At first, I thought it was some kind of caching thing, so I tried a rather unusual string literal:

if ("whuiwhqohqweihqweohi" == "whuiwhqohqweihqweohi")

仍然可以正常工作在MSVC和g ++上。那是依赖实现的行为吗?我知道比较在编译时已知的变量不是很有用,但是我的问题是情况如何?。

Still works fine both on MSVC and g++. Is that an implementation dependent behavior? I understand that comparing variables which are known at compile-time is not very useful, but my question is just "how come this is the case?".

另外,使用 auto 似乎也可以:

Additionally, using auto seems to be also working:

#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 在这里是什么类型?

This code produces the correct output. What is the type of a and b here?

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

推荐答案

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

You have to be very careful here, as some of the cases you're looking at aren't quite equivalent to others.

在第一个示例中:

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

if (a == b)

您要创建两个<字符的em> arrays ,每个均从字符串文字初始化。然后,您尝试将这些阵列相互比较。在大多数情况下(包括此情况),数组的名称将求值为该数组中第一个元素的地址。因此,您实际上是在比较两个阵列的地址。那些不能相同,因此保证比较得出 false

You're creating two arrays of char, each initialized from an string literal. You're then attempting to compare those arrays to each other. In most cases (including this one) the name of an array evaluates to the address of the first element in that array. So you're really comparing the addresses of the two arrays. Those can't be the same, so the comparison is guaranteed to yield false.

在第二个示例中: if( aaa == aaa),您要比较的是字符串文字自身,而不是根据字符串文字初始化的数组。

In your second example: if ("aaa" == "aaa"), you're comparing the string literals themselves, rather than arrays initialized from the string literals.

标准不保证这样做的结果。该标准允许(但不要求)将相同的字符串文字合并在一起。同样,您真正要比较的不是字面量的内容,而是它们存储的地址。如果编译器合并了字符串文字,因此它们位于相同的地址,则将生成 true 。如果将它们分开,则会产生 false

The result of this is not guaranteed by the standard. The standard allows (but does not require) that identical string literals be merged together. Again, however, what you're really comparing isn't the contents of the literals--it's the addresses at which they're stored. If the compiler merges the string literals so they're at the same address, this will yield true. If it keeps them separate, it'll yield false.

在您的 auto case:

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

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

You have pretty much the same situation--a and b both end up as pointers to char, holding the addresses of the string literals. If the compiler merges those literals, they'll both point to the same address so they'll compare equal. If the compiler doesn't merge them together, each will have its own address, and they'll compare as not equal.

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

The big point here is that none of these is comparing the contents of the strings at all, only the addresses at which they're stored. The content counts only to the degree that two string literals can only be merged if they have (or at least end with) the same content.

结尾为,我指的是这样一个事实:如果您有以下内容,则是编译器: wing 在一个位置,而 swing 在另一种情况下,编译器可以自由地合并两者,因此可以使用以下代码:

As far as "at least end with" goes, I'm referring to the fact that a compiler if you had something like: "wing" in one place and "swing" in another, the compiler is free to merge the two, so with code something like:

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

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

...the compiler could store swing in one place, and initialize a to point to the second character of that stored literal.

这篇关于C ++字符串文字相等性检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆