意外的输出为零

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了意外的输出为零相关的知识,希望对你有一定的参考价值。

我是C ++的新手,目前正在单一链接列表上练习。不知何故,下面代码的输出始终为零。我认为问题是nextPoint方法但是我尝试更改引用/解除引用,它不起作用。

问题出在哪儿?先感谢您。

// Singly Linked List

#include <math.h>
#include <iostream>

class Point {

        public:
        double x, y;
        Point* next;

        // constructor
        Point (double x, double y) {
                this->x = x;
                this->y = y;
                this->next = NULL;
        }

        void nextPoint(Point nexti) {
                this->next = &nexti;
        }

        double dist(Point &a, Point &b) {
                double dx = a.x - b.x;
                double dy = a.y - b.y;
                return sqrt(dx*dx - dy*dy);
        }

        double length() {
                Point *iter = this;
                double len = 0.0;
                while (iter->next != NULL) {
                        len += dist(*iter, *iter->next);
                        iter = iter->next;
                }
                return len;
        }

};

int main() {

        Point p1(1,1);
        Point p2(2,2);
        Point p3(5,5);
        p1.nextPoint(p2);
        p2.nextPoint(p3);

        std::cout << p1.length() << std::endl;

        return 1;

}
答案

请打开更多的编译器警告,你可能会收到警告,在nextPoint中你永久存储临时变量(nexti)的地址(在this->next中)。

您必须传递要添加的点的地址或引用。

void nextPoint(Point *nexti) {
    this->next = nexti;
}

p1.nextPoint(&p2);
p2.nextPoint(&p3);

要么

void nextPoint(Point &nexti) {
    this->next = &nexti;
}

p1.nextPoint(p2);
p2.nextPoint(p3);

旁注:请用NULL替换nullptr

另一答案

您的代码有两个问题:

  1. nextPoint通过值获取其参数,这意味着您将存储该by-value参数的地址,该参数在nextPoint的执行结束后立即变为无效。改变它接受Point &nexti
  2. 您的距离计算功能错误。你应该添加正方形,而不是减去它们:return sqrt(dx*dx + dy*dy);

与您的问题无关,但有几种方法可以改进您的代码:

  • 使用构造函数中的mem-initialiser列表初始化成员而不是分配给成员。这是一个很好的习惯,因为一旦你开始处理初始化和赋值大不相同的事情(引用,类,......),这将是有用的。 Point (double x, double y) : x(x), y(y), next(nullptr) {}
  • 使用nullptr而不是NULL,因为后者不是类型安全的。
  • length应该标记为const,因为它不会修改它所调用的对象。请注意,iter同样已更改为const Point *double length() const { const Point *iter = this; double len = 0.0; while (iter->next != NULL) { len += dist(*iter, *iter->next); iter = iter->next; } return len; }
  • dist根本不使用this,所以它可以(并且应该)成为static成员函数。此外,它应该通过const &获取其参数,因为它不会修改它们: static double dist(const Point &a, const Point &b) { double dx = a.x - b.x; double dy = a.y - b.y; return sqrt(dx*dx - dy*dy); }

以上是关于意外的输出为零的主要内容,如果未能解决你的问题,请参考以下文章

为啥此代码片段返回意外结果?

xml 中的 Android 谷歌地图片段。我得到“意外的命名空间前缀”

重新加载表数据时出现致命错误:展开为零:需要帮助

意外的label和tableview发现nil

加载库存表视图时出现致命错误(发现为零)

VS:_BitScanReverse64内在的意外优化行为