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