[英]Linked list - new Node pointer vs. new Node variable
我正在创建一个练习链接列表,但遇到了问题。
我已经创建2个类似代码和在第一个我创建某些structure called Node
作为一个variable
和在第二代码创建一个structure called Node
作为一个pointer
。
我认为它应该以相同的方式工作,但事实并非如此。 我将发布代码,并查看名为addNode()
的函数。
我还有一个下一个问题:为什么我必须传递这样的指针: addNode( Node *& head, Node *& tail )
才能使其正常工作,而不是将它们作为addNode( Node * head, Node * tail )
传递。
第一个代码(错误):
#include <iostream>
#include <string>
using namespace std;
struct Node{
int val;
Node * prev;
Node * next;
Node( int val ) : val( val ) { }
};
void printList( Node * ptr ){
while( ptr != NULL ){
cout << ptr -> val << " ";
ptr = ptr -> next;
}
cout << endl;
}
void addNode( int val, Node *& head, Node *& tail ){
Node tmp( val );
if( head == NULL ){
head = &tmp;
tail = &tmp;
tmp . prev = NULL;
tmp . next = NULL;
}
else{
tail -> next = &tmp;
tmp . prev = tail;
tmp . next = NULL;
tail = &tmp;
}
}
int main(){
Node * head = NULL;
Node * tail = NULL;
addNode( 3, head, tail );
addNode( 8, head, tail );
addNode( 2, head, tail );
addNode( 4, head, tail );
addNode( 15, head, tail );
addNode( 11, head, tail );
/*Node b( 5 );
cout << b . val << endl;
*/
printList( head );
return 0;
}
第二个代码(好):
#include <iostream>
#include <string>
using namespace std;
struct Node{
int val;
Node * prev;
Node * next;
Node( int val ) : val( val ) { }
};
void printList( Node * ptr ){
while( ptr != NULL ){
cout << ptr -> val << " ";
ptr = ptr -> next;
}
cout << endl;
}
void addNode( int val, Node *& head, Node *& tail ){
Node * tmp = new Node( val );
if( head == NULL ){
head = tmp;
tail = tmp;
tmp -> prev = NULL;
tmp -> next = NULL;
}
else{
tail -> next = tmp;
tmp -> prev = tail;
tmp -> next = NULL;
tail = tmp;
}
}
int main(){
Node * head = NULL;
Node * tail = NULL;
addNode( 3, head, tail );
addNode( 8, head, tail );
addNode( 2, head, tail );
addNode( 4, head, tail );
addNode( 15, head, tail );
addNode( 11, head, tail );
/*Node b( 5 );
cout << b . val << endl;
*/
printList( head );
return 0;
}
如果执行Node tmp
,则退出定义范围后tmp
被销毁。
在另一方面,这样做Node *tmp = new Node
的分配内存Node
上堆和给你一个指针tmp
它。 仅当您在其上调用delete
时,该Node
才被销毁。
进入问题的第二部分,如果需要修改指针而不是指针指向的对象,则希望通过引用传递指针。
如果执行head = tmp, tail = tmp
而不通过引用传递head
和tail
,那么head
和tail
将只保留该值,直到该函数的范围为止。 此更改不会反映在addNode()
。
为了使用功能修改head
和tail
,必须通过引用(即第二代码段)传递它们。 在第一个代码段中,它们是通过value传递的,在函数addNode()
内进行的任何修改都将在函数超出范围后消失。
情况1 :按值传递
addNode(head); // call
功能体:
void addNode(Node *headCopy) { // Node *headCopy = head, copy is created
headCopy = &someThing; // the copy of head point to something else
// not the actual 'head' that changes its pointee
}
情况2 :通过引用传递
addNode(&head);
功能体:
void addNode(Node *&headReference) { // reference to 'head'
headReference = &someThing; // the actual 'head' changes its pointee
}
由于原始指针的复制操作便宜,因此没有理由通过引用传递它。
void addNode( int val, Node *& head, Node *& tail ){
Node tmp( val ); // tmp - local variable
if( head == NULL ){
head = &tmp; // address of local variable
tail = &tmp; // above
tmp . prev = NULL;
tmp . next = NULL;
}
else{
tail -> next = &tmp; // above
tmp . prev = tail;
tmp . next = NULL;
tail = &tmp; // above
}
} // local variable tmp get destructed, tail head contain address of unexisting object
它是一个双向链接列表,并在Node构造函数中更改Node成员val或参数val的名称,添加head(nullptr),tail(nullptr),否则不会为NULL
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.