所以我对链表如何工作以及如何在C ++中保留引用感到有些困惑。
例如,我有一个列表,让我们说 myList ,我想打印它的项目 我从学校知道我必须将我的列表复制到另一个列表,以便在打印过程后保持 myList 相同。
Node* n;
n = myList;
while(n)
{
printf("%d ",n->val);
n=n->next;
}
好的,所以我在另一个列表中有一个myList的副本n(带有相同的指针)。 在我循环遍历n之后,myList是相同的但是具有相同的指针,如n。
如果n改变了为什么myList没有改变(同样的指针,对吧?)?
现在,如果我说:
Node* n;
n = myList;
n->next = NULL;//or n->next=another node -doesn t matter
现在在第二个例子中,myList也被改变了。
你能解释一下吗?
答案 0 :(得分:9)
我认为你对实际列表结构和列表结构的引用之间的区别感到困惑。
在你的第一个例子中,关于遍历列表,你在遍历之前基本上有这种情况,你有两个对同一个列表的引用:
o-->o-->o-->o-->o-->NULL
^
|
\_ myList, n
遍历列表后,看起来像这样:
o-->o-->o-->o-->o-->NULL
^ ^
| |
\_ myList \_ n
如果你没有复制列表头部的引用来遍历它,你会在遍历后得到这个:
o-->o-->o-->o-->o-->NULL
^
|
\_ myList
由于您不再有指向列表头部的指针,因此您无法访问该列表。
在你的第二个例子中,你有这个:
o-->o-->o-->o-->o-->NULL
^
|
\_ myList, n
你把它变成了这个:
_________________
/ \
o o-->o-->o-->o-->NULL
^
|
\_ myList, n
这种转换会改变列表的实际结构,这将反映在对该列表的所有引用中。
答案 1 :(得分:4)
如果更改指针n
,它将不会与指针mylist
的值相同...它们是两个单独的指针,最初指向同一个对象,因为您生成了来自n
中值的副本的mylist
的初始值。
话虽如此,如果你从n
中的值初始化后没有调整mylist
的值,那么这两个指针指向同一个对象。如果你取消引用指针并修改它们指向的对象,那么两个指针,因为它们指向同一个对象,将反映对所指向的对象的更改。
最后,因为您只是将mylist
的值复制到n
,所以只有一个链接列表...您没有制作列表的“深层”副本。因此,如果您修改任何一个指针所指向的实际列表节点,那么将修改实际列表。
答案 2 :(得分:3)
n = myList;
使n
指向与myList
相同的元素。它们本质上是相同的 - 除了你可以重新分配n
,但是当它们指向相同的位置时,你还没有真正制作列表的副本 - 只是指向第一个节点的指针的副本
因为它们指向同一位置,n->next = NULL;
会修改这两个列表。
答案 3 :(得分:1)
您尚未创建单独的列表,也没有修改原始列表;你只是使用n
遍历列表,依次指向每个元素(有点像通过数组索引)。