First, note that your code (and some of the previous solutions) will never infer the last item from the list. Do you want to
if (*head != NULL) ...
Further, passing a pointer to a pointer will work. But itβs better to make the list title as follows:
typedef struct node_s { struct node_s *next; ... data declaration here } Node; typedef struct list_s { struct node_s *head; } List; void init_list(List *list) { list->head = NULL; }
Now declare the list as follows:
List list[1]; init_list(list);
Declaring an array of one element makes each link to list pointer automatically, which excludes a lot of & in your code. Then it's nice and clean to implement push and pop:
void push(List *list, Node *node) { node->next = list->head; list->head = node; } Node *pop(List *list) { Node *head = list->head; if (head) { list->head = head->next; head->next = NULL; } return head; }
Why is it better? Say that you later decided to keep the number of items in the list. With a separate node header, this is very simple:
typedef struct list_s { struct node_s *head; int length; } List; void init_list(List *list) { list->head = NULL; length = 0; } void push(List *list, Node *node) { node->next = list->head; list->head = node; ++list->length; } Node *pop(List *list) { Node *head = list->head; if (head) { list->head = head->next; head->next = NULL; --list->length; } return head; }
Please note that the call code should not change. With a pointer to a pointer approach, you are at a dead end. There are many other uses where a separate list heading makes your code more flexible for future changes.
source share