equal函数在比较C风格字符串的向量时为什么返回true?

huangapple go评论61阅读模式
英文:

Why does the equal function return true when comparing vectors of C-style strings?

问题

  1. 在第一种情况下,向量只是用字符串字面值初始化,然后将这些字符串的迭代器传递给equal函数。结果为true。由于C风格字符串没有比较运算符,它们的地址被比较,但当输出向量中字符串的地址时,显示地址不相等。为什么equal函数的结果仍然为true呢?

  2. 在第二种情况下,向量已经从指向C风格字符串的指针初始化。在这种情况下,同样返回true,尽管字符串的地址再次不同。为什么?

  3. 在第三种情况下,向量使用二维数组初始化。在这种情况下,向量中字符串的地址再次不同,但这次输出结果为false

英文:

Please explain why in some cases it is true and in other cases it is false, although in all three cases the addresses of the strings are different?

  1. In the first case, vectors are simply initialized with string literals and then iterators of those strings are passed to the equal function.
    The result is true.
    Since C-style strings have no comparison operators, their addresses are compared, but when the addresses of strings in vectors are output, it shows that the addresses are not equal. Why then does the result of the equal function get true?

  2. In the second case, vectors are already initialized from pointers to C-style strings. In this case true is also returned, though again the string addresses are different. Why?

  3. In the third case, vectors are initialized using two-dimensional arrays. In this case, again, the addresses of strings in vectors are different, but this time the output is false

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

int main()
{
	std::cout << std::boolalpha;

	std::vector<const char*> vec_e{ "String" };
	std::vector<const char*> vec_f{ "String" };
	std::cout << equal(vec_e.begin(), vec_e.end(), vec_f.begin()) << std::endl; // true
	std::cout << &vec_e[0] << std::endl;
	std::cout << &vec_f[0] << std::endl;

	const char* str_a[1] = { "Hello" };
	const char* str_b[1] = { "Hello" };
	std::vector<const char*> vec_a(std::begin(str_a), std::end(str_a));
	std::vector<const char*> vec_b(std::begin(str_b), std::end(str_b));
	std::cout << equal(vec_a.begin(), vec_a.end(), vec_b.begin()) << std::endl; // true
	std::cout << &vec_a[0] << std::endl;
	std::cout << &vec_b[0] << std::endl;

	const char str_c[][6] = { "World" };
	const char str_d[][6] = { "World" };
	std::vector<const char*> vec_c(std::begin(str_c), std::end(str_c));
	std::vector<const char*> vec_d(std::begin(str_d), std::end(str_d));
	std::cout << equal(vec_c.begin(), vec_c.end(), vec_d.begin()) << std::endl; // false
	std::cout << &vec_c[0] << std::endl;
	std::cout << &vec_d[0] << std::endl;

	return 0;
}

答案1

得分: 4

以下是您要翻译的内容:

"All 3 compare the addresses, not the strings. The first 2 compare the addresses of string literals, which can be the same when the strings are equal.

The first 2 examples can be rewritten as:

const char *a = "Hello";
const char *b = "Hello";
cout << (a == b);

It is implementation defined if a and b point to the same address or if the compiler uses 2 separate string literals.

The third one is:

const char a[] = "Hello";
const char b[] = "Hello";
cout << (a == b);

where the arrays obviously don't have the same address.

The &vec_e[0] are wrong in the std::cout, they should be (void*)vec_e[0], then it will tell you the addresses, which are compared. The cast is necessary, otherwise it would print the string, not the address.

#include
#include
#include
#include

int main()
{
std::cout << std::boolalpha;

std::vector<const char*> vec_e{ "String" };
std::vector<const char*> vec_f{ "String" };
std::cout << equal(vec_e.begin(), vec_e.end(), vec_f.begin()) << std::endl; // true
std::cout << (void*)vec_e[0] << std::endl;
std::cout << (void*)vec_f[0] << std::endl;

const char* str_a[6] = { "Hello" };
const char* str_b[6] = { "Hello" };
std::vector<const char*> vec_a(std::begin(str_a), std::end(str_a));
std::vector<const char*> vec_b(std::begin(str_b), std::end(str_b));
std::cout << equal(vec_a.begin(), vec_a.end(), vec_b.begin()) << std::endl; // true
std::cout << (void*)vec_a[0] << std::endl;
std::cout << (void*)vec_b[0] << std::endl;

const char str_c[][6] = { "World" };
const char str_d[][6] = { "World" };
std::vector<const char*> vec_c(std::begin(str_c), std::end(str_c));
std::vector<const char*> vec_d(std::begin(str_d), std::end(str_d));
std::cout << equal(vec_c.begin(), vec_c.end(), vec_d.begin()) << std::endl; // false
std::cout << (void*)vec_c[0] << std::endl;
std::cout << (void*)vec_d[0] << std::endl;

return 0;
}

will print

true
0x4030a0
0x4030a0
true
0x4030e0
0x4030e0
false
0x7fffd05dcb70
0x7fffd05dcb90"

英文:

All 3 compare the addresses, not the strings. The first 2 compare the addresses of string literals, which can be the same when the strings are equal.

The first 2 examples can be rewritten as:

const char *a = &quot;Hello&quot;;
const char *b = &quot;Hello&quot;;
cout &lt;&lt; (a == b);

It is implementation defined if a and b point to the same address or if the compiler uses 2 separate string literals.

The third one is:

const char a[] = &quot;Hello&quot;;
const char b[] = &quot;Hello&quot;;
cout &lt;&lt; (a == b);

where the arrays obviously don't have the same address.

The &amp;vec_e[0] are wrong in the std::cout, they should be (void*)vec_e[0], then it will tell you the addresses, which are compared. The cast is necessary, otherwise it would print the string, not the address.

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;numeric&gt;

int main()
{
    std::cout &lt;&lt; std::boolalpha;

    std::vector&lt;const char*&gt; vec_e{ &quot;String&quot; };
    std::vector&lt;const char*&gt; vec_f{ &quot;String&quot; };
    std::cout &lt;&lt; equal(vec_e.begin(), vec_e.end(), vec_f.begin()) &lt;&lt; std::endl; // true
    std::cout &lt;&lt; (void*)vec_e[0] &lt;&lt; std::endl;
    std::cout &lt;&lt; (void*)vec_f[0] &lt;&lt; std::endl;

    const char* str_a[6] = { &quot;Hello&quot; };
    const char* str_b[6] = { &quot;Hello&quot; };
    std::vector&lt;const char*&gt; vec_a(std::begin(str_a), std::end(str_a));
    std::vector&lt;const char*&gt; vec_b(std::begin(str_b), std::end(str_b));
    std::cout &lt;&lt; equal(vec_a.begin(), vec_a.end(), vec_b.begin()) &lt;&lt; std::endl; // true
    std::cout &lt;&lt; (void*)vec_a[0] &lt;&lt; std::endl;
    std::cout &lt;&lt; (void*)vec_b[0] &lt;&lt; std::endl;

    const char str_c[][6] = { &quot;World&quot; };
    const char str_d[][6] = { &quot;World&quot; };
    std::vector&lt;const char*&gt; vec_c(std::begin(str_c), std::end(str_c));
    std::vector&lt;const char*&gt; vec_d(std::begin(str_d), std::end(str_d));
    std::cout &lt;&lt; equal(vec_c.begin(), vec_c.end(), vec_d.begin()) &lt;&lt; std::endl; // false
    std::cout &lt;&lt; (void*)vec_c[0] &lt;&lt; std::endl;
    std::cout &lt;&lt; (void*)vec_d[0] &lt;&lt; std::endl;

    return 0;
}

will print

true
0x4030a0
0x4030a0
true
0x4030e0
0x4030e0
false
0x7fffd05dcb70
0x7fffd05dcb90

huangapple
  • 本文由 发表于 2023年2月6日 17:38:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75359559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定