-
Notifications
You must be signed in to change notification settings - Fork 2
Quick Start
This is a quick start guide meant for tutors!
Run the following or just go to Releases and download llv.h from the latest release
curl -s https://api.github.com/repos/BraedonWooding/LLV/releases/latest \
| grep "browser_download_url.*llv.h" \
| cut -d '"' -f 4 \
| wget -qi -You can follow above if you want the single source file or you can install it like a library (it is static for ease). To install it like a library just write wget https://raw.githubusercontent.com/BraedonWooding/LLV/master/install.sh && sh install.sh && rm install.sh
TODO: Currently you can just go to releases and download the llv.h file :).
NOTE: if you are using it as a static library you have to compile it with
-lLLV(like-lm)
Have a look at the examples for some specific examples (the code is under the .incl you could also look at the tests) but I'll give a few good examples here too;
eg1.c
// If you are on cse or did the single header route just write
#include "llv.h"
// else you have to list everything you are going to use like;
// #include <LLV/collections/ll.h>
// #include <LLV/llv.h>
int main(void) {
LL list = ll_new("Example List");
update(1, list); // prints out the list (which will be empty)
for (int i = 0; i < 10; i++) {
// NEW_NODE is a special generic macro that will create data
// correctly with the proper type tag
// in this case it is ll_new_node((Data){i}, INTEGER)
ll_append(list, NEW_NODE(ll, i));
update(1, list);
}
// LL and DLL have `head` and `tail`
LL_Node cur = list->head;
// this means that as you update cur
// It'll display what box it currently is pointing to
// cur can be null as well in that case it'll point to nothing
attach_ptr(&cur, "cur");
update(1, list);
// sidenote: you can also call SET_PTR(cur, "cur"); and UNSET_PTR(cur);
// if for a specific reason you don't want it to track and update
// also remember to deattach_ptr(&cur); at the end if you care about freeing
while (cur != NULL) {
// read data as int
// not typesafe so know what you are doing!!
if (cur->data.int_data % 2 != 0) {
// remove node
LL_Node tmp = cur;
cur = cur->next;
ll_remove_node(list, tmp); // this also returns the removed node
// sidenote: you could write this out yourself
// by carrying around a prev ptr (or calling ll_find_prev)
// fmt_update is a fancy printf basically
fmt_update("%l %s %n", list, "Removed Node:", tmp);
ll_free_node(tmp); // if you care
} else {
cur = cur->next;
update(1, list);
}
}
fmt_update("%s %l", "Finished Removing Odd Nodes", list);
deattach_ptr(&cur, "cur");
ll_free(list);
}Run like gcc -o eg1.out eg1.c
Things to try (mainly so you can understand how things work);
-
export LLV_SLEEP_TIME=1000before you run the program (no need to recompile) -
update(2, list, list);(you should see the same list replicated twice!) will need to recompile of course
This time we will build the list till the user enters 0 then we will remove all even elements
eg2.c
// If library
// #include <LLV/collections/ll.h>
// #include <LLV/llv.h>
// Else
#include "llv.h"
#include <stdio.h>
#include <stdlib.h>
int main(void) {
LL list = ll_new("Example List");
int res;
while(true) {
// %i for input then `i` for int
// valid ones are: %ii (int) %il (long) %ic (char) %is (char buf - no allocation) %if (double)
// note: they must all be at the end!!
fmt_update("%l %ii", list, &res);
if (res == -1) break;
ll_append(list, NEW_NODE(ll, res));
}
LL_Node cur = list->head;
attach_ptr(&cur, "cur");
update(1, list);
while (cur != NULL) {
if (cur->data.int_data % 2 == 0) {
LL_Node tmp = cur;
cur = cur->next;
ll_remove_node(list, tmp);
fmt_update("%l %s %n", list, "Removed Node:", tmp);
ll_free_node(tmp);
} else {
cur = cur->next;
}
}
fmt_update("%s %l", "Finished Removing Even Nodes", list);
deattach_ptr(&cur, "cur");
ll_free(list);
}Run like gcc -o eg2.out eg2.c
Things to try;
- Notice how sleep time doesn't effect the insertion only when it is doing the removal this is because input overrides any sleep settings
- Try floating point numbers!
Get user input for an ll of floats till the user enters 0, then get an upper and lower bound and everything outside those bounds must be removed!
eg3.c
// If library
// #include <LLV/collections/ll.h>
// #include <LLV/llv.h>
// Else
#include "llv.h"
#include <stdio.h>
#include <stdlib.h>
int main(void) {
LL list = ll_new("Example List");
double res;
while(true) {
fmt_update("%l %if", list, &res);
// 0 has an actual proper value so epsilon isn't needed
// here since we aren't doing arithmetic on it
if (res == 0) break;
// NEW_NODE picks up on it being a double and doesn't care!!! yay
ll_append(list, NEW_NODE(ll, res));
}
double lower, upper;
// no need to have lists here we just want a lower and upper bound but why not
fmt_update("%l %s %if %if", list, "Enter lower and then upper bound", &lower, &upper);
LL_Node cur = list->head;
attach_ptr(&cur, "cur");
update(1, list);
while (cur != NULL) {
if (cur->data.flt_data < lower || cur->data.flt_data > upper) {
LL_Node tmp = cur;
cur = cur->next;
ll_remove_node(list, tmp);
fmt_update("%l %s %n", list, "Removed Node:", tmp);
ll_free_node(tmp);
} else {
cur = cur->next;
}
}
fmt_update("%s %l", "Finished Removing Nodes out of bounds", list);
deattach_ptr(&cur, "cur");
ll_free(list);
}Run like gcc -o eg2.out eg2.c
Things to try;
- Remove the list in the code that grabs lower/upper bounds to show that you don't need it!