In the first code example, the node variable is a pointer to a node structure. It contains the address of the memory cell in which the node structure is stored.
In the second code example, the variable node is a pointer to a pointer to a node structure. It contains the address of the memory cell containing the address of the memory cell in which the node structure is stored.
This sounds confusing to a large extent, because the variable name is the same in both code samples, and it almost matches the node . Let me rewrite the code samples so that the meaning of the pointer is clearer.
The first case:
Node* node_pointer = head; while (node_pointer != NULL) {
Second case:
Node** node_pointer_pointer = &head; while (*node_pointer_pointer != NULL) { // node_pointer_pointer points to a pointer which points to a Node // do something to that Node, then advance to the next element in the list // ... something ... node_pointer_pointer = &((*node_pointer_pointer)->next); // advance }
In both cases, the head variable is a pointer to a node structure. Therefore, its value is assigned directly to node_pointer in the first case:
node_pointer = head;
And in the second case, the & operator is used to get the head memory cell:
node_pointer_pointer = &head;
What is node ? This is a struct containing (possibly along with other things) the next field, which is a pointer to a node . Therefore, the next value can be assigned directly to node_pointer in the first code example, but in the second stage of the code it needs to refer to the & operator.
Why is the second approach useful? This is not the case in this example. If you only want to iterate over the elements of a linked list, all you need is a pointer to the node structure.
However, it is useful to have a pointer to a pointer when you want to manipulate a subordinate pointer. For example, suppose you have finished moving the list, and now you want to add a new tail to the node.
In the first case above, node_pointer does not help, since its value is NULL . You can't do anything about it.
In the second case, when the *node_pointer_pointer value is NULL , the node_pointer_pointer value node_pointer_pointer not. This is the address of the next field of the last node in the list. Therefore, we can assign the address of the new node structure to this next :
*node_pointer_pointer = make_new_node();
Note the asterisk or dereference operator in *node_pointer_pointer . By delaying node_pointer_pointer , we get the next pointer, and we can assign it the address of the new node structure.
Also note that this assignment works if node_pointer_pointer points to the head of an empty list. By dereferencing this, we get head , and we can assign it the address of the new node structure.