// gcc -o taste taste.c // ./taste #include #include typedef struct node_t { int value; struct node_t *next; } node; /* We'll have to update the head pointer when the list is empty so we get a reference to it, not a copy. */ void add_entry(node **head, int new_value) { // A reference to the last pointer. Starts out pointing to the head. node ***indirect = &head; node *new_node = malloc(sizeof(node)); new_node->value = new_value; new_node->next = NULL; while(**indirect != NULL) { *indirect = &(**indirect)->next; } // indirect now points to the last pointer in the list whether it was empty or not **indirect = new_node; } /* Returns a pointer to the node that contains the value we're looking for or NULL if not found. */ node *find_entry(node *head, int value) { node *current = head; while(current != NULL && current->value != value) { current = current->next; } return current; } /* The head pointer may need to be modified so we need a double pointer. The entry pointer is also passed by reference as we'll free that memory. */ void remove_entry(node **head, node **entry) { /* The indirect pointer point to the pointer that we'll update */ node ***indirect = &head; /* Walk the list as long as we haven't found the pointer we're looking for */ while((**indirect) != *entry) { *indirect = &(**indirect)->next; } /* We remove it. indirect, which now points to either null or to the pointer that points to the entry we want to delete, is set to whatever comes after that entry. */ **indirect = (*entry)->next; free(*entry); } void print_list(node *head) { node *current = head; while(current != NULL) { printf("%d ", current->value); current = current->next; } printf("\n"); } int main(int argc, char const *argv[]) { node *head = NULL; print_list(head); add_entry(&head, 4); add_entry(&head, 3); add_entry(&head, 10); add_entry(&head, 2); add_entry(&head, 7); print_list(head); node *entry = find_entry(head, 2); remove_entry(&head, &entry); entry = find_entry(head, 4); remove_entry(&head, &entry); print_list(head); return 0; }