周
(周)
1
题目:试调以下代码。调出来的人将被颁发“代码巨佬”奖项。
目标:给定一些点对,求他们两两之间的欧几里得距离。
注意:本挑战不是做出以上目标就能完成的,而是需要答出为什么以下代码错误并指出如何修改。
有答案请在本帖下面回复,我会在 8月 6 日之前 24h 之内回复 WA / AC。
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
struct point {
float x, y;
};
float distance(point* p1, point* p2)
{
return sqrt((p1->x - p2->x) * (p1->x - p2->x) + (p1->y - p2->y) * (p1->y - p2->y));
}
int main()
{
vector<point> po;
point p1 = { 0, 0 }, p2 = { 1, 1 };
po.push_back(p1); po.push_back(p2);
for (auto i = po.begin(); i != po.end(); i++)
for (auto j = po.begin(); j != po.end(); j++)
cout << distance(i, j) << " ";
}
// Output: 0 1 -1 0
// Expected Output: 0 1.414... 1.414... 0
5 个赞
苍穹一粟
(。)
5
@周 吧 point *
改为 std::vector<point>::iterator
5 个赞
苍穹一粟
(。)
6
因为遍历 std::vector
返回的是迭代器而非指针
5 个赞
曾天云
(曾天云)
8
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
struct point {
float x, y;
};
float distance(vector<point>::iterator p1, vector<point>::iterator p2)
{
return sqrt((p1->x - p2->x) * (p1->x - p2->x) + (p1->y - p2->y) * (p1->y - p2->y));
}
int main()
{
vector<point> po;
point p1 = { 0, 0 }, p2 = { 1, 1 };
po.push_back(p1); po.push_back(p2);
for (auto i = po.begin(); i != po.end(); i++)
for (auto j = po.begin(); j != po.end(); j++)
cout << distance(i, j) << " ";
}
迭代器和指针不对应
5 个赞
周
(周)
9
:)答对了,此贴终结
补充说明:
迭代器不等于指针。他们两个的关系为:
point* ptr;
std::vector<point>::iterator it;
ptr = &*it; // 正确用法
但是,编译器不能使用 &*
这样隐式转换,需要你自己加。因此,按理来说,以上代码会 CE(没有可取函数)。
那为什么是 WA 而不是 CE 呢?这涉及到一个本题另外一个细节:distance(iterator, iterator)
调用了标准库的 std::distance
,是另外一个函数。因为我定义的 distance
函数不匹配,因此编译器就默认匹配了 std::distance
。
看一下标准库的这个神奇函数:
说白了,就是在测试合法性后直接返回 _Last - _First
,也就是两个地址的内存距离,而 vector<int>
中当然会输出 0, 1, -1, 0
。
于是解释完了。
5 个赞
信友队蔡老师
(密涅瓦的猫头鹰)
13
到时候私信我哈,弄漂亮一点,不要梗图啥的,热度过去就不好看了
5 个赞