我使用c ++ book阅读了编程原理和练习中编写的代码。
struct Link {
string value;
Link* prev;
Link* succ;
Link(const string& v, Link* p = nullptr, Link* s = nullptr)
: value{v}, prev{p}, succ{s} { }
};
我喜欢他的教学方法,从一个空壳开始并向上工作(他/他指的是本书的作者)。 因此,在他第一次尝试建立一个名单(北欧神)时,他这样做了:
Link* norse_gods = new Link{"Thor",nullptr,nullptr};
norse_gods = new Link{"Odin",nullptr,norse_gods};
norse_gods–>succ–>prev = norse_gods;
norse_gods = new Link{"Freia",nullptr,norse_gods};
norse_gods–>succ–>prev = norse_gods;
我的困惑在于他必须明确说明这一点:
norse_gods–>succ–>prev = norse_gods;
见于第三和第五行。
我在考虑添加项目而没有明确说明每次添加之间的代码行也会起作用。 即:
Link* norse_gods = new Link{"Thor",nullptr,nullptr};
norse_gods = new Link{"Odin",nullptr,norse_gods};
norse_gods = new Link{"Freia",nullptr,norse_gods};
我的思维状态是错误的吗?为什么必须将该行(norse_gods–>succ–>prev = norse_gods;
)显式添加到代码
答案 0 :(得分:5)
我们说A <--> B
说A->succ == B
和B->prev == A
。在第1行之后,你有:
norse_gods == Thor
第2行之后你有:
norse_gods == Odin ---> Thor
此处的问题是Odin->succ == Thor
,但Thor->prev == nullptr
。因为列表中的每个元素都有一个指向其前一个元素和后一个元素的指针,所以这是一个双向链接列表,旨在两个方向遍历,但是现在它只能遍历一个(从左到右)。通过制作Thor->prev == Odin
可以纠正此问题。自Odin->succ == Thor
和norse_gods == Odin
起,我们就可以在Thor->prev
行中访问和更改norse_gods->succ->prev = norse_gods;
。之后你有:
norse_gods == Odin <--> Thor