在 C++ 中将指针传递给函数
Passing pointers to function in c++
有人能告诉我为什么退出函数 reverse
时指针 head
和 tail
不同吗?
struct elem{
int val;
elem* prev;
elem* next;
...
};
void print(elem* head,elem* tail){...}
void insertAtEnd(elem* e,elem* tail){...}
void reverse(elem* head,elem* tail){
elem* headref = head;
elem* temp = head;
while(temp != NULL){
elem* t = temp->prev;
temp->prev = temp->next;
temp->next = t;
temp = temp->prev;
}
head = tail;
tail = headref;
print(head,tail);
}
int main(){
elem* head = new elem();
elem* tail = new elem();
...
print(head,tail);
reverse(head,tail);
print(head,tail);
return 0;
}
print()
内部函数 reverse
工作正常。接下来 print
(就在 main
中的 return 0
之前)导致分段错误(head->next
指向 NULL
)。
使用void reverse(elem* head,elem* tail)
,您不修改指针(您可以修改内容)。
你的意思可能是
void reverse(elem*& head, elem*& tail)
修改head
和tail
。
main()
中的指针本身在调用reverse()
后并没有改变,因为你将它们按值传递给reverse()
,而函数中的代码只修改了自己的副本 个指针。但是,它们指向的 elem
个对象的内容 已被 reverse()
函数更改。
也就是说,main()
中的head
仍然指向它以前指向的同一个elem
对象,但是现在elem
对象是列表(因为您在 reverse()
函数中更改了它的内容,现在它的 next
成员是 nullptr
)。类似地,main()
中的 tail
指向现在是列表头部的 elem
。
调用 reverse 不会改变 head 和 tail 因为它们是按值传递的(reverse 只修改它的私有副本)。如果将 reverse 的声明更改为
void reverse(elem *&head, elem *&tail)
应该可以。
没有详细分析你的代码,当你逆向时,你传递的是指向你的元素的指针,所以称为 head 的现在是 tail,而称为 tail 的现在是 head。
所以之后你需要print( tail, head )
您的 print
函数显然不会检查 null
也就是说,如果 next
在到达您的 tail
之前为 nullptr,它将导致访问冲突。这将是因为 head
是尾巴所以它的 next
确实是 nullptr.
如果您确实希望 reverse
函数更改指针本身以及它们指向的内容,那么您会得到一个反向列表,其中名称 head
和 tail
交换了, 通过引用传递它们。
您在 reverse() 中交换指针是本地的。一旦离开功能范围,它将被丢弃。要实现交换,yo0u必须使用双指针:
void reverse(elem** head, elem** tail){
elem* headref = *head;
elem* temp = *head;
while(temp != NULL){
elem* t = temp->prev;
temp->prev = temp->next;
temp->next = t;
temp = temp->prev;
}
*head = *tail;
*tail = headref;
print(*head,*tail);
}
并传递头尾地址:
reverse(&head, &tail);
P.S。抱歉可能存在错误 - 我没有测试代码
有人能告诉我为什么退出函数 reverse
时指针 head
和 tail
不同吗?
struct elem{
int val;
elem* prev;
elem* next;
...
};
void print(elem* head,elem* tail){...}
void insertAtEnd(elem* e,elem* tail){...}
void reverse(elem* head,elem* tail){
elem* headref = head;
elem* temp = head;
while(temp != NULL){
elem* t = temp->prev;
temp->prev = temp->next;
temp->next = t;
temp = temp->prev;
}
head = tail;
tail = headref;
print(head,tail);
}
int main(){
elem* head = new elem();
elem* tail = new elem();
...
print(head,tail);
reverse(head,tail);
print(head,tail);
return 0;
}
print()
内部函数 reverse
工作正常。接下来 print
(就在 main
中的 return 0
之前)导致分段错误(head->next
指向 NULL
)。
使用void reverse(elem* head,elem* tail)
,您不修改指针(您可以修改内容)。
你的意思可能是
void reverse(elem*& head, elem*& tail)
修改head
和tail
。
main()
中的指针本身在调用reverse()
后并没有改变,因为你将它们按值传递给reverse()
,而函数中的代码只修改了自己的副本 个指针。但是,它们指向的 elem
个对象的内容 已被 reverse()
函数更改。
也就是说,main()
中的head
仍然指向它以前指向的同一个elem
对象,但是现在elem
对象是列表(因为您在 reverse()
函数中更改了它的内容,现在它的 next
成员是 nullptr
)。类似地,main()
中的 tail
指向现在是列表头部的 elem
。
调用 reverse 不会改变 head 和 tail 因为它们是按值传递的(reverse 只修改它的私有副本)。如果将 reverse 的声明更改为
void reverse(elem *&head, elem *&tail)
应该可以。
没有详细分析你的代码,当你逆向时,你传递的是指向你的元素的指针,所以称为 head 的现在是 tail,而称为 tail 的现在是 head。
所以之后你需要print( tail, head )
您的 print
函数显然不会检查 null
也就是说,如果 next
在到达您的 tail
之前为 nullptr,它将导致访问冲突。这将是因为 head
是尾巴所以它的 next
确实是 nullptr.
如果您确实希望 reverse
函数更改指针本身以及它们指向的内容,那么您会得到一个反向列表,其中名称 head
和 tail
交换了, 通过引用传递它们。
您在 reverse() 中交换指针是本地的。一旦离开功能范围,它将被丢弃。要实现交换,yo0u必须使用双指针:
void reverse(elem** head, elem** tail){
elem* headref = *head;
elem* temp = *head;
while(temp != NULL){
elem* t = temp->prev;
temp->prev = temp->next;
temp->next = t;
temp = temp->prev;
}
*head = *tail;
*tail = headref;
print(*head,*tail);
}
并传递头尾地址:
reverse(&head, &tail);
P.S。抱歉可能存在错误 - 我没有测试代码