问题
I am writing a C code to find the middle of linked list. I understood the logic but was unable to figure out how pointers are being used. What is the difference in the way Node *head
and Node** head_ref
work?
void middle(struct Node *head) ;
void push(struct Node** head_ref, int new_data) ;
回答1:
In the first function header, *head
is a pointer to a node object which is allocated somewhere in memory:
void middle(struct Node *head);
_____________________
| |
*head --> | Node object |
| [val=1][*next=NULL] |
|_____________________|
while in the second function header, **head_ref
is a pointer to a pointer to a node object somewhere in memory:
void push(struct Node** head_ref, int new_data);
_____________________
| |
*head --> | Node object |
^ | [val=1][*next=NULL] |
| |_____________________|
|
**head_ref
This is another layer of indirection. Why is the second construct necessary? Well, if I want to modify something allocated outside of my function scope, I need a pointer to its memory location. In the first example, I can dereference the *head
pointer (with head->
) to access the underlying Node
object in memory and make modifications to it or access its properties.
Taking this logic to the next level of indirection, if I want to push a new Node
object onto the front of the list to make it the new head, I need to modify the head
pointer itself. Just as when I wanted to manipulate the Node
object with a pointer, now I need a pointer to *head
(which simply happens to be a pointer rather than a Node
object) in order to modify it.
Here's the contents of push
and a before/after function call:
void push(struct Node** head_ref, int new_data) {
Node *new_head = malloc(sizeof(Node)); // allocate memory for the new head node
new_head->data = new_data; // set its value
new_head->next = *head_ref; // make it point to the
// old head pointer
*head_ref = new_head; // make it the new head by modifying
// the old head pointer directly
}
/* Before push */
_____________________
| |
*head --> | Node object |
^ | [val=1][*next=NULL] |
| |_____________________|
|
**head_ref
/* After calling push(&head, 2);
* ^
* `&` operator gets the memory address of `head`,
* which is a pointer.
*/
_________________ _____________________
| | | |
*head --> | Node object | | Node object |
^ | [val=2] [*next]----->| [val=1][*next=NULL] |
| |_________________| |_____________________|
|
**head_ref
Here's a full example:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
void push(Node** head_ref, int new_data) {
Node *new_head = malloc(sizeof(Node));
new_head->data = new_data;
new_head->next = *head_ref;
*head_ref = new_head;
}
void print(Node *head) {
while (head) {
printf("%d->", head->data);
head = head->next;
}
puts("NULL");
}
void free_list(Node *head) {
while (head) {
Node *tmp = head;
head = head->next;
free(tmp);
}
}
int main() {
Node *head = malloc(sizeof(Node));
head->next = NULL;
head->data = 1;
printf("Before push:\n");
print(head);
push(&head, 2);
printf("\nAfter push:\n");
print(head);
free_list(head);
return 0;
}
Output:
Before push:
1->NULL
After push:
2->1->NULL
回答2:
struct Node *head - > Here the pointer head is a pointer to the head of the Linked List. Head is a pointer which can point to a node structure.
eg.
If you have a linked list like this :- ____ ____ _____ |_1__|--->|_2__|--->|_3__|--->....... address- 1000 1004 1008
Your Node *head will be a pointer variable holding the address of the node with value 1(address of the head node which is the node storing the value 1). Content of head=1000
struct Node **head_ref -> here the head_ref is the pointer to the pointer of the start of the linked list.
eg.
If you have a linked list like this :- ____ ____ _____ |_1__|--->|_2__|--->|_3__|--->....... address- 1000 1004 1008 | *head address- 5050 | **head
Your Node *head will be a pointer variable holding the address of the node with value 1(address of the head node which is the node storing the value 1). Content of head=1000 Content of **head_ref will be the address of the head pointer i.e, 5050.
**head_ref is used for indirect reference.
来源:https://stackoverflow.com/questions/55654934/what-is-the-difference-between-node-head-versus-node-head