README.md
This project has been created as a little side project of the 42 curriculum by lenivorb aka Lexxythelizard.
Lexlists is a small personal C library created during my journey through the 42 curriculum. \
It explores linked lists in C from two perspectives: simple headless node-based lists and
structured list heads that keep track of metadata such as length,
list information, first node and last node. The project is mainly a learning tool,
but also a reusable foundation for future C projects like 42_lexscan.
Clone this repository and call
make allto create the library in the root of the repository.
The header to include lexlist.h is also in the root of this repository
Include this library in your files:
#include "[path to dir]/lexlist.h"Compile your files with:
cc [your flags] [your files] -L [path to library] -l lexlist -o [your program name]Leftover .o files can be removed anytime by calling
make cleanThe following resources were useful while working on this project:
Common webpages
- GeeksforGeeks : https://www.geeksforgeeks.org/c/c-programming-language/
- Stack Overflow : https://stackoverflow.com/questions
- cc for compiling
- make for build automation
- ar for creating the static library
- valgrind for memory checking
- custom test files for checking functions in the terminal
AI assistance was used for:
- chasing typos, because I am so clumsy ;)
t_nodet_head
t_node
t_node is basically a simple linked list node which can point to any content type
and to the next node, additionally, it can be indexed.
This enables a few more possibillites: See headless functions
typedef struct s_node
{
int idx;
void *content;
t_node *next;
} t_node;t_head
t_head is the head which keeps track of the length, stores the info about the list
and points to the first node of a list (member .tail / head -> tail)
the member .tip / head -> tip always points to the last element of tail
--> the tip of tail :)
typedef struct s_head
{
int len;
void *info;
t_node *tail;
t_node *tip;
} t_head;headless_init_new_listheadless_add_backheadless_add_frontheadless_lastheadless_by_idxheadless_pop_by_indexheadless_popheadless_clear_nodeheadless_clear_node_simpleheadless_clear_listheadless_clear_list_simpleheadless_cutheadless_reindexheadless_count
lexlist__appendlexlist__getlexlist__initlexlist__insertlexlist__pop_idxlexlist__poplexlist__dellexlist__rmlexlist__striplexlist__del_simplelexlist__rm_simplelexlist__strip_simple
Use the list without the head and without OOP just very basic :)
headless_init_new_list
- Param 1:
voidcontent - Return:
t_node*new_list - NOTE: the only headless function which
takes a pointer to content and create (allocates) a new node.
use it to create a pointer to a new node
headless_add_back
- Param 1:
t_node**node - Param 2:
t_node*new - Return: ---
- NOTE: adds node to the end of the list,
makes *node new if *node was NULL (list was empty)
headless_add_front
- Param 1:
t_node**node - Param 2:
t_node*new - Return:
t_node*new_first node - NOTE: makes new the new first node and appends the list as new -> next
be careful and make sure to pass the first node of the list
headless_by_idx
- Param 1:
t_node*node - Param 2:
intidx - Return:
t_node*searched_node/NULLif not found - NOTE: returns a pointer to the node with idx
node remains in list
headless_last
- Param 1:
t_node*node - Return:
t_node*last_node/NULLif list empty - NOTE: simple and safe function, could be called on any node in the list
headless_pop_by_index
- Param 1:
t_node**node - Param 2:
intidx - Return:
t_node*searched_node/NULLif not found - NOTE: returns a pointer to the node with idx
node gets removed from the list, list stays intact due to reconnection:
popped | prev -> next = popped -> next;
headless_pop
- Param 1:
t_node**node - Return:
t_node*last_node/NULLif list empty - NOTE: simple and safe function, could be called on any node in the list,
pops the last node of the list and removes it from the list
popped | prev -> next = NULL;
headless_clear_node
- Param 1:
t_node**node - Param 2:
void(*del_content)(void*) - Return:
intidx of removed node - NOTE: calling
del_contenton(*node)->contentto free and delete content
for easily freeable content, like str just useheadless_clear_node_simple
be careful: it basically deleting one node and its content
without reconnecting the list: could breake the list
headless_clear_node_simple
- Param 1:
t_node**node - Return:
intidx of removed node - NOTE: calling
del_contenton(*node)->contentto free and delete
easily freeable content, like str.
be careful: it basically deleting one node and its content
without reconnecting the list: could breake the list
headless_clear_list
- Param 1:
t_node**node - Param 2:
void(*del_content)(void*) - Return:
intidx of removed node - NOTE: calling
clear_nodeiteratively on any node until the end
passingdel_contentevery time.
useheadless_clear_list_simplefor easily freeable content like str.
headless_clear_list_simple
- Param 1:
t_node**node - Return:
intidx of removed node - NOTE: calling
clear_nodeiteratively on any node until the end
passingdel_contentevery time.
use it only for easily freeable content like str.
headless_cut
- Param 1:
t_node**node - Param 2:
intidx - Return:
t_nodecutfirst node of cut-off list \ - NOTE: cuts the list at idx inclusive
sets(headless_get_by_idx(*node, (idx - 1)))-> next = NULL;
headless_cut([node 0], 3)| stays {node 0, node 1, node 2} |
cut {node 3, node 4, ..., node n}
headless_reindex
- Param 1:
t_node*first - Return:
intreindexednumber of reindexed elements - NOTE: reindexing every node in ascending order,
make sure to call it at the head
Use it after you popped one element or after you calledheadless_add_front
headless_count
- Param 1:
t_node*node - Return:
intcount - NOTE: could be used at any node to count the elements until the end
make sure to pass the first node if you want to know the whole length
lexlist__append
- Param 1:
t_head*self - Param 2:
void*content - Return:
intidxindex of appended element - NOTE: the original ...
appends a new element (node) at the end of the list (tail)
assigns idx to new element and updateshead -> tipautomatically
new_element = {idx: old len, content: <content> next: NULL}
allocates memory fornew_element
lexlist__get
- Param 1:
t_head*self - Param 2:
intidx - Return:
void*content/NULLif element not found - NOTE: returns pointer to content of element
list remains unchanged
lexlist__init
- Param 1:
void*info - Return:
t_head*new_headpointer to new head - NOTE: inits a new head and assigning info
new_head = {len: 0, info: <info> tail: NULL, tip: NULL}
allocates memory fornew_head
lexlist__insert
- Param 1:
t_head*self - Param 2:
void*content - Param 3:
intidx - Return:
intself -> lenthe new len - NOTE: inserts a new element into the list at idx if 0 <= idx <= self -> len
reindexes theself -> tailand updatesself -> tipautomatically
allocates memory fornew_element
lexlist__pop_idx
- Param 1:
t_head*self - Param 2:
intidx - Return:
void*contentof last elementidx: idxin list - NOTE: element will be removed from the list
automatically updates head -> len and head -> tip
lexlist__pop
- Param 1:
t_head*self - Return:
void*contentof last element in list - NOTE: the element will be removed from the list without breaking the list
automatically updates head -> len and head -> tip
automatically reindexes the elements
lexlist__del
- Param 1:
t_head*self - Param 2:
void(*rm_info)(void*) - Param 3:
void(*rm_content)(void*) - Return:
intlenof elements removed - NOTE: removes all elements
head -> tailcompletely, removeshead -> info
be careful, this function does not free head itself,
use if head was not allocated or for other occasions
MAKE SURE to pass a workingrm_infoand a validrm_contentfunction
uselexlist__del_simplefor easily freeable content and info variables
lexlist__rm
- Param 1:
t_head**self - Param 2:
void(*rm_info)(void*) - Param 3:
void(*rm_content)(void*) - Return:
intlenof elements removed - NOTE: removes all elements
head -> tailcompletely, removeshead -> info
by callinglexlist__del
finally, it frees the head and setshead = NULL
MAKE SURE to pass a workingrm_infoand a validrm_contentfunction
uselexlist__rm_simplefor easily freeable content and info variables
lexlist__strip
- Param 1:
t_head**self - Param 2:
void(*rm_info)(void*) - Return:
void**strippedNULL terminated void pointer array of contents - NOTE: strips all elements of
(*head)->tailmeans: iteratively removes all of its
elements but storing its content inNULLterminatedvoid**array
which can be freed separately
MAKE SURE to pass a workingrm_infofunction
uselexlist__strip_simple()for easily freeable info variables
lexlist__del_simple
- Param 1:
t_head*self - Return:
intlenof elements removed - NOTE: removes all elements
head -> tailcompletely, removeshead -> info
be careful, this function does not free head itself,
use if head was not allocated or for other occasions
MAKE SURE just to use it for easily freeable content and info variables
lexlist__rm_simple
- Param 1:
t_head**self - Return:
intlenof elements removed - NOTE: removes all elements
head -> tailcompletely, removeshead -> info
by callinglexlist__del
finally, it frees the head and setshead = NULL
MAKE SURE just to use it for easily freeable content and info variables
lexlist__strip_simple
- Param 1:
t_head**self - Return:
void**strippedNULL terminated void pointer array of contents - NOTE: strips all elements of
(*head)->tailmeans: iteratively removes all of its
elements but storing its content inNULLterminatedvoid**array
which can be freed separately
MAKE SURE just to use it for easily freeable info variables
Lexxythelizard
42 Berlin login: lenivorb
private GitHub: https://www.github.com/Lexxythelizard