Arrays and linked list
parent
46f0946e62
commit
a6d1d6ce77
@ -0,0 +1,10 @@
|
|||||||
|
P=array_exp
|
||||||
|
OBJECTS=
|
||||||
|
CFLAGS = -g -Wall -O3
|
||||||
|
LDLIBS=
|
||||||
|
CC=gcc
|
||||||
|
|
||||||
|
$(P): $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(P)
|
@ -0,0 +1,23 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define ARRLEN 10
|
||||||
|
|
||||||
|
int my_array[ARRLEN];
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
size_t i, j; // guaranteed to be wide enough to address all memory locations. Better than unsigned int.
|
||||||
|
|
||||||
|
for (i = 0; i < ARRLEN; i++)
|
||||||
|
{
|
||||||
|
my_array[i] = i + 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output each array element's values
|
||||||
|
for (j = 0; j < ARRLEN; j++)
|
||||||
|
{
|
||||||
|
printf("Element[%zu] = %d\n", j, my_array[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1,14 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
|
||||||
|
byte a = 0x41; // A
|
||||||
|
byte b = 0x61; // a
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
byte c = b - a;
|
||||||
|
printf("The value of a - b is %d\n", c);
|
||||||
|
printf("The hex value of c is: 0x%02x\n", c);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
.PHONY: clean
|
||||||
|
P=linked_list
|
||||||
|
OBJECTS= linked_list.o
|
||||||
|
CFLAGS = -g -Wall -O3
|
||||||
|
LDLIBS=''
|
||||||
|
CC=gcc
|
||||||
|
|
||||||
|
$(P): $(OBJECTS)
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(P)
|
@ -0,0 +1,162 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*This is a doubly linked list*/
|
||||||
|
|
||||||
|
/*Struct to make it easy*/
|
||||||
|
typedef struct Node
|
||||||
|
{
|
||||||
|
/* data */
|
||||||
|
int data;
|
||||||
|
struct Node *next; // Pointer to the next element
|
||||||
|
struct Node *previous; // Pointer to the previous element
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
/*
|
||||||
|
**pheadNode should be interpreted as first obtain pointer to Node. Then by dereferencing that pointer you
|
||||||
|
are able to set the value at that address. This is why we use the & address of operator. It is saying
|
||||||
|
Provide the address of the pointer variable. Use that to obtain a pointer to that address location, then
|
||||||
|
derefence that pointer to assign a value to it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void insert_at_beginning(Node **pheadNode, int value);
|
||||||
|
void insert_at_end(Node **pheadNode, int value);
|
||||||
|
|
||||||
|
void print_list(Node *headNode);
|
||||||
|
void print_list_backwards(Node *headNode);
|
||||||
|
|
||||||
|
void free_list(Node *headNode);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
printf("Just so you know a Node in our linked list is %lu bytes\n", sizeof(Node));
|
||||||
|
/*Sometimes in a doubly linked list the last node is also stored*/
|
||||||
|
Node *head = NULL; // Pointers to the front of the list
|
||||||
|
|
||||||
|
printf("Inserting a node at the beginning of the list.\n");
|
||||||
|
insert_at_beginning(&head, 5); // Sets data at *head to 5
|
||||||
|
print_list(head);
|
||||||
|
|
||||||
|
printf("Insert a node at the beginning, then print the list backwards.\n");
|
||||||
|
insert_at_beginning(&head, 10);
|
||||||
|
print_list_backwards(head); // should print 5, 10
|
||||||
|
|
||||||
|
printf("Insert a node at the end and then print the list.\n");
|
||||||
|
|
||||||
|
insert_at_end(&head, 15);
|
||||||
|
print_list(head);
|
||||||
|
|
||||||
|
free_list(head);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_list_backwards(Node *headNode)
|
||||||
|
{
|
||||||
|
if (headNode == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Iterate through the list, and once we get to the end, iterate backwards to print
|
||||||
|
out the items in reverse order (this is done with the pointer to the previous node). This can be done even more easily if a pointer to the last node is stored.
|
||||||
|
*/
|
||||||
|
Node *i = headNode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
An Arrow operator in C/C++ allows to access elements in Structures and Unions.
|
||||||
|
It is used with a pointer variable pointing to a structure or union.
|
||||||
|
|
||||||
|
Use Dot(.) with struct values
|
||||||
|
Use -> to with struct pointer
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (i->next != NULL)
|
||||||
|
{
|
||||||
|
i = i->next; // sets the pointer to the next pointer of the struct.
|
||||||
|
}
|
||||||
|
// i points to the last element of the list now
|
||||||
|
while (i != NULL)
|
||||||
|
{
|
||||||
|
printf("Value: %d\n", i->data);
|
||||||
|
i = i->previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_list(Node *headNode)
|
||||||
|
{
|
||||||
|
Node *i = headNode;
|
||||||
|
|
||||||
|
while (i != NULL)
|
||||||
|
{
|
||||||
|
printf("Value: %d\n", i->data);
|
||||||
|
i = i->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_at_beginning(Node **pheadNode, int value)
|
||||||
|
{
|
||||||
|
Node *currentNode;
|
||||||
|
|
||||||
|
if (pheadNode == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentNode = malloc(sizeof *currentNode); //deref pointer;
|
||||||
|
|
||||||
|
currentNode->next = NULL;
|
||||||
|
currentNode->previous = NULL;
|
||||||
|
currentNode->data = value;
|
||||||
|
|
||||||
|
if (*pheadNode == NULL) // list is empty
|
||||||
|
{
|
||||||
|
*pheadNode = currentNode; // set the object at pheadNode memory location to currentNode which is on the heap.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentNode->next = *pheadNode;
|
||||||
|
(*pheadNode)->previous = currentNode;
|
||||||
|
*pheadNode = currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_at_end(Node **pheadNode, int value)
|
||||||
|
{
|
||||||
|
Node *currentNode;
|
||||||
|
|
||||||
|
if (pheadNode == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentNode = malloc(sizeof *currentNode);
|
||||||
|
Node *i = *pheadNode; //save a ref to the current head so we can traverse the list
|
||||||
|
|
||||||
|
currentNode->data = value;
|
||||||
|
currentNode->next = NULL;
|
||||||
|
currentNode->previous = NULL;
|
||||||
|
|
||||||
|
if (*pheadNode == NULL) // If pheadNode is NULL meaning an empty list
|
||||||
|
{
|
||||||
|
*pheadNode = currentNode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i->next != NULL) // Go to the end of the list
|
||||||
|
{
|
||||||
|
i = i->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
i->next = currentNode;
|
||||||
|
currentNode->previous = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_list(Node *node)
|
||||||
|
{
|
||||||
|
while (node != NULL)
|
||||||
|
{
|
||||||
|
Node *next = node->next;
|
||||||
|
free(node);
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#define ASIZE (10)
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
int *p = NULL;
|
||||||
|
int my_array[ASIZE];
|
||||||
|
|
||||||
|
/* Setting up the the values of the array to i * i*/
|
||||||
|
for (i = 0; i < ASIZE; i++)
|
||||||
|
{
|
||||||
|
// square the arrary index
|
||||||
|
my_array[i] = i * i; // Interesting enough th size_t is unsigned long which will be converted to int
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reading the values using a pointer */
|
||||||
|
for (p = my_array; p < my_array + ASIZE; ++p)
|
||||||
|
{
|
||||||
|
printf("%d\n", *p); // dereference the memory location
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h> // Start using EXIT_SUCCESS
|
||||||
|
|
||||||
|
int *int_point_plus_one(int *ptr)
|
||||||
|
{
|
||||||
|
/* Recieves a pointer to an integer and adds 1 to it */
|
||||||
|
printf("%p has a value of: %d\n", ptr, *ptr); //Second call is dereferencing the int at ptr location in mem
|
||||||
|
// deference the location and deference the value add one to the value, return the pointer
|
||||||
|
*ptr = *ptr + 1;
|
||||||
|
printf("%p now has a value of: %d\n", ptr, *ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int a = 67;
|
||||||
|
int *p = &a;
|
||||||
|
|
||||||
|
int_point_plus_one(p);
|
||||||
|
int_point_plus_one(p);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue