我在处理一个小项目时偶然发现了这个问题。
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<int*> v;
for (int x = 1; x < 6; ++x)
{
int * a = new int(x);
v.push_back(a);
}
unsigned int y = 4;
for (auto a : v)
{
std::cout << "BEFORE SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
std::swap(a, v[y]);
std::cout << "AFTER SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
std::cout << "==========" << std::endl;
--y;
}
// for (std::vector<int*>::iterator it = v.begin(); it != v.end(); ++it)
// {
// std::cout << "BEFORE SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
// std::swap(*it, v[y]);
// std::cout << "AFTER SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
// std::cout << "==========" << std::endl;
// --y;
// }
// inb4 "You forgot to deallocate!" This is an example.
}
在代码的最后,有两个循环执行完全相同的任务但是以不同的方式。
带有auto
关键字的for循环会产生缺少数字的结果:
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 5
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
带迭代器的for循环按预期工作:
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 5
AFTER SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
AFTER SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 5
==========
auto
循环是怎么回事?为什么我会失去价值观?
这是一个CPP.SH链接,可以自己查看:http://cpp.sh/2ve3
答案 0 :(得分:3)
for(auto a : v)
你实际上得到的是值的副本,而不是数组中的就地值。
您需要通过将循环声明为for(auto&a : v)
功能示例:
for (auto& a : v)
{
std::cout << "BEFORE SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
std::swap(a, v[y]);
std::cout << "AFTER SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
std::cout << "==========" << std::endl;
--y;
}
如果您现在尝试跟踪程序的执行情况,因为您知道它是一个值而不是引用,那么您将发现结果是有意义的。
现在您已了解其工作原理,您只需使用标准库即可实现您在一次通话中尝试执行的操作:
std::reverse(myvector.begin(),myvector.end());
示例: http://www.cplusplus.com/reference/algorithm/reverse/?kw=reverse
答案 1 :(得分:0)
此处数组值的副本存储在变量&#34; a&#34;中。 a不是对ur数组的值的引用。这就是为什么当你交换两个变量时它被交换但是在变量a。不在数组的实际值中。因为你的另一个交换参数是数组的值,它取值变量a。这就是为什么你没有得到理想的输出。 auto a:v的声明实际上是声明,如下所示:
a=v[0];
a=v[1]; (on next iteration)
等等。 正如你所看到的那样,只有数组值的副本没有引用。这就是你获得这种输出的原因。