-
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=1000
before 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!