【问题标题】:Why does the `equal` works for const char* in C++?为什么 `equal` 在 C++ 中适用于 const char*?
【发布时间】:2013-02-16 13:59:33
【问题描述】:

代码是这样的,它输出1:

int main(int argc, char *argv[])
{
    vector <const char*> vec = {"nima","123"};
    vector <const char*> vec2 = {"nima","123"};
    auto result = equal(vec.cbegin(), vec.cend(), vec2.cbegin());
    cout << result << endl;
    return 0;
}

我知道只有使用strcmp 才能测试两个c 风格的字符串是否相等(因为char* 不是我理解的对象)。但这里equal 是来自&lt;algorithm&gt; 的函数。它是否重载了== 运算符,以便它可以测试两个char* 的相等性?

@Damon 说它们是相等的,因为我理解将相同的字符串文字合并到相同的地址。但是,当我尝试使用不同地址的char* 时,它仍然给了我相同的结果:

int main(int argc, char *argv[])
{
char* k = "123";
char* b = "123";
vector <const char*> vec = {"nima"};
vector <const char*> vec2 = {"nima"};
cout << &k << endl;
cout << &b << endl;
vec.push_back(k);
vec2.push_back(b);

auto result = equal(vec.cbegin(), vec.cend(), vec2.cbegin());
cout << result << endl;
return 0;
}

结果是:

 0x7fff5f73b370
 0x7fff5f73b368
 1

【问题讨论】:

  • This demo 可能会让发生的事情更清楚。
  • 关于您的编辑,请尝试动态分配char 字符串,您应该为每个字符串获得不同的地址,从而产生不同的结果。
  • @juanchopanza 我明白了,当我将其更改为 cout &lt;&lt; (int*)k &lt;&lt; (int*) b &lt;&lt; endl; 时,它们是相同的,谢谢!

标签: c++ string algorithm stl char


【解决方案1】:

这里可能发生的是编译器/链接器将其中两个相同的四个字符串文字合并为两个文字。因此,"nima""123" 都具有相同的地址。

您将地址存储在向量中并比较它们(地址上的operator==)。由于地址相同,所以比较相等。

请注意,这是意外。它之所以“有效”,有两个原因:

  1. 字符串是文字(也就是说,不是从例如stdin 读取的某些字符串)。
  2. 允许使用编译器,但不需要合并相同的文字(是否发生这种情况由实现定义)。

这可能会导致两种情况让您感到意外(如果您必须找出为什么它在一直“工作”时突然无法工作,那就不是那么有趣了),或者当您使用不同的编译器或即使是具有不同优化设置的相同编译器,或者当您分配非文字字符串时。

【讨论】:

  • “实施定义”可能比“意外”更好。相关的标准引用是 §2.14.5/12:“是否所有字符串文字都是不同的(即存储在不重叠的对象中)是实现定义的。”
  • 没错,但我也想指出,当您使用例如添加两个从stdin 读取的相同字符串。它在示例中“有效”的事实(由于实现定义的行为)也可以被认为是偶然的。我会尽量不那么含糊地改写它。
  • 我修改了这个例子,让两个“123”有不同的地址。但是,它不会改变结果..
  • @Firegun 您将kb(不同)的地址与它们指向的字符串的地址(相同)混淆了。
  • @sftrabbit: 你的意思是std::cout &lt;&lt; (void const*)k &lt;&lt; "\n";,否则打印c-string的内容。
猜你喜欢
  • 2022-08-19
  • 2010-09-09
  • 1970-01-01
  • 2012-07-21
  • 2023-04-02
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多