While I'm training to get better at C, I tried my hand at making a doubly linked list implementation.
linkedlist.h
#ifndef LINKED_LIST_H_
#define LINKED_LIST_H_
#include <stdlib.h>
typedef struct node {
void* data;
struct node *next;
struct node *prev;
} node;
typedef node* pnode;
typedef struct List {
pnode head, tail;
} *List;
List init_list();
void push_back(List, void*);
void* pop_back(List);
void push_front(List, void*);
void* pop_front(List);
void foreach(List, void (*func)(void*));
void free_list(List);
void clear(List);
int size(List);
#endif /* LINKED_LIST_H_ */
linkedlist.c
#include "linkedlist.h"
List init_list() {
List list = (List)malloc(sizeof(struct List));
list->head = NULL;
list->tail = NULL;
return list;
}
void push_back(List list, void* data) {
pnode temp = (pnode)malloc(sizeof(struct node));
temp->data = data;
temp->next = NULL;
temp->prev = NULL;
if(!(list->head)) {
list->head = temp;
list->tail = temp;
} else {
list->tail->next = temp;
temp->prev = list->tail;
list->tail = list->tail->next;
}
}
void push_front(List list, void* data) {
pnode temp = (pnode)malloc(sizeof(struct node));
temp->data = data;
temp->next = NULL;
temp->prev = NULL;
if(!(list->tail)) {
list->head = temp;
list->tail = temp;
} else {
list->head->prev = temp;
temp->next = list->head;
list->head = list->head->prev;
}
}
void* pop_front(List list) {
if(!(list->tail)) return NULL;
pnode temp = list->head;
if(list->head == list->tail) {
list->head = list->tail = NULL;
} else {
list->head = list->head->next;
list->head->prev = NULL;
}
void* data = temp->data;
free(temp);
return data;
}
void* pop_back(List list) {
if(!(list->head)) return NULL;
pnode temp = list->tail;
if(list->tail == list->head) {
list->tail = list->head = NULL;
} else {
list->tail = list->tail->prev;
list->tail->next = NULL;
}
void* data = temp->data;
free(temp);
return data;
}
void free_list(List list) {
while(list->head) {
pop_back(list);
}
free(list);
}
void clear(List list) {
while(list->head) {
pop_back(list);
}
}
void foreach(List list, void(*func)(void*)) {
pnode temp = list->head;
if(temp) {
while(temp) {
(*func)(temp->data);
temp = temp->next;
}
}
}
int size(List list) {
int i = 0;
pnode temp = list->head;
while(temp) {
i++;
temp = temp->next;
}
return i;
}
Can you please point out any flaws, errors, stupid mistakes, general improvements, which can make this code better and "C'ish"?