Arrays and linked list

master
Drew Bednar 4 years ago
parent 46f0946e62
commit a6d1d6ce77

@ -1,4 +1,4 @@
CLEANSUBDIRS ?= types structs static pointers hello headers functions file_io env_vars
CLEANSUBDIRS ?= types structs static pointers hello headers functions file_io env_vars linked_list
cleanall:
@for subdir in $(CLEANSUBDIRS); do \

@ -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;
}

@ -1,6 +1,7 @@
# import <stdio.h>
#include <stdio.h>
int main(){
int main()
{
char name[10] = "Laura";

@ -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;
}
}

@ -1,5 +1,6 @@
CFLAGS=-Wall -O3
PROGRAMS=simple_pointer adv_pointer char_pointer
PROGRAMS=simple_pointer adv_pointer char_pointer pointer_func array_pointer
all: $(PROGRAMS)
@ -12,9 +13,11 @@ adv_pointer:
char_pointer:
gcc -o char_pointer $(CFLAGS) char_pointer.c
# NOT IMPLEMENTED
#array_pointer:
# gcc -o array_pointer -Wall -O1 array_pointer.c
pointer_func:
gcc -o pointer_func $(CFLAGS) pointer_func.c
array_pointer:
gcc -o array_pointer -Wall -O1 array_pointer.c
clean:
rm -f $(PROGRAMS)

@ -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;
}

@ -10,3 +10,4 @@ $(P): $(OBJECTS)
clean:
rm -f *.o $(P)

Loading…
Cancel
Save