Add CT331 Programming Paradigms
This commit is contained in:
Binary file not shown.
@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
int my_int;
|
||||
int* my_int_pointer;
|
||||
long my_long;
|
||||
double * my_double_pointer;
|
||||
char ** my_char_pointer_pointer;
|
||||
|
||||
printf("The size of my_int is %lu bytes\n", sizeof(my_int));
|
||||
printf("The size of my_int_pointer is %lu bytes\n", sizeof(my_int_pointer));
|
||||
printf("The size of my_long is %lu bytes\n", sizeof(my_long));
|
||||
printf("The size of my_double_pointer is %lu bytes\n", sizeof(my_double_pointer));
|
||||
printf("The size of my_char_pointer_pointer is %lu bytes\n", sizeof(my_char_pointer_pointer));
|
||||
}
|
8
third/semester1/CT331: Programming Paradigms/assignments/assignment1/code/question2/.idea/.gitignore
generated
vendored
Normal file
8
third/semester1/CT331: Programming Paradigms/assignments/assignment1/code/question2/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/question2.iml" filepath="$PROJECT_DIR$/.idea/question2.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
Binary file not shown.
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include "linkedList.h"
|
||||
#include "tests.h"
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
runTests();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "linkedList.h"
|
||||
|
||||
typedef struct listElementStruct{
|
||||
char* data;
|
||||
size_t size;
|
||||
struct listElementStruct* next;
|
||||
} listElement;
|
||||
|
||||
//Creates a new linked list element with given content of size
|
||||
//Returns a pointer to the element
|
||||
listElement* createEl(char* data, size_t size){
|
||||
listElement* e = malloc(sizeof(listElement));
|
||||
if(e == NULL){
|
||||
//malloc has had an error
|
||||
return NULL; //return NULL to indicate an error.
|
||||
}
|
||||
char* dataPointer = malloc(sizeof(char)*size);
|
||||
if(dataPointer == NULL){
|
||||
//malloc has had an error
|
||||
free(e); //release the previously allocated memory
|
||||
return NULL; //return NULL to indicate an error.
|
||||
}
|
||||
strcpy(dataPointer, data);
|
||||
e->data = dataPointer;
|
||||
e->size = size;
|
||||
e->next = NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
//Prints out each element in the list
|
||||
void traverse(listElement* start){
|
||||
listElement* current = start;
|
||||
while(current != NULL){
|
||||
printf("%s\n", current->data);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
//Inserts a new element after the given el
|
||||
//Returns the pointer to the new element
|
||||
listElement* insertAfter(listElement* el, char* data, size_t size){
|
||||
listElement* newEl = createEl(data, size);
|
||||
listElement* next = el->next;
|
||||
newEl->next = next;
|
||||
el->next = newEl;
|
||||
return newEl;
|
||||
}
|
||||
|
||||
//Delete the element after the given el
|
||||
void deleteAfter(listElement* after){
|
||||
listElement* delete = after->next;
|
||||
listElement* newNext = delete->next;
|
||||
after->next = newNext;
|
||||
//need to free the memory because we used malloc
|
||||
free(delete->data);
|
||||
free(delete);
|
||||
}
|
||||
|
||||
// returns the number of elements in the list
|
||||
int length(listElement* list) {
|
||||
int length = 0;
|
||||
listElement* current = list;
|
||||
|
||||
// traversing the list and counting each element
|
||||
while(current != NULL){
|
||||
length++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
// push a new element onto the head of a list and update the list reference using side effects
|
||||
void push(listElement** list, char* data, size_t size) {
|
||||
// create the new element
|
||||
listElement* newElement = createEl(data, size);
|
||||
|
||||
// handle malloc errors
|
||||
if (newElement == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// make the the new element point to the current head of the list
|
||||
newElement->next = *list;
|
||||
|
||||
// make the list reference to point to the new head element
|
||||
*list = newElement;
|
||||
}
|
||||
|
||||
|
||||
// pop an element from the head of a list and update the list reference using side effects
|
||||
// assuming that the desired return value here is the popped element, as is standard for POP operations
|
||||
listElement* pop(listElement** list) {
|
||||
// don't bother if list is non existent
|
||||
if (*list == NULL) { return NULL; }
|
||||
;
|
||||
// getting reference to the element to be popped
|
||||
listElement* poppedElement = *list;
|
||||
|
||||
// make the the second element the new head of the list -- this could be NULL, so the list would be NULL also
|
||||
*list = (*list)->next;
|
||||
|
||||
// detach the popped element from the list
|
||||
poppedElement->next = NULL;
|
||||
|
||||
return poppedElement;
|
||||
}
|
||||
|
||||
|
||||
// enque a new element onto the head of the list and update the list reference using side effects
|
||||
// essentially the same as push
|
||||
void enqueue(listElement** list, char* data, size_t size) {
|
||||
// create the new element
|
||||
listElement* newElement = createEl(data, size);
|
||||
|
||||
// handle malloc errors
|
||||
if (newElement == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// make the the new element point to the current head of the list
|
||||
newElement->next = *list;
|
||||
|
||||
// make the list reference to point to the new head element
|
||||
*list = newElement;
|
||||
}
|
||||
|
||||
|
||||
// dequeue an element from the tail of the list by removing the element from the list via side effects, and returning the removed item
|
||||
// assuming that we want to return the dequeued element rather than the list itself, as enqueue returns nothing and uses side effects, so dequeue should also use side effects
|
||||
listElement* dequeue(listElement* list) {
|
||||
// there are three cases that we must consider: a list with 0 elements, a list with 1 element, & a list with >=2 elements
|
||||
|
||||
// don't bother if list is non existent
|
||||
if (list == NULL) { return NULL; }
|
||||
|
||||
// if there is only one element in the list, i.e. the head element is also the tail element, just returning this element
|
||||
// this means that the listElement pointer that was passed to this function won't be updated
|
||||
// ideally, we would set it to NULL but we can't do that since `list` is a pointer that has been passed by value, so we can't update the pointer itself. we would need a pointer to a pointer to have been passed
|
||||
if (list->next == NULL) {
|
||||
return list;
|
||||
}
|
||||
|
||||
// traversing the list to find the second-to-last element
|
||||
listElement* current = list;
|
||||
while (current->next->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// get reference to the element to be dequeued
|
||||
listElement* dequeuedElement = current->next;
|
||||
|
||||
// make the penultimate element the tail by removing reference to the old tail
|
||||
current->next = NULL;
|
||||
|
||||
return list;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
#ifndef CT331_ASSIGNMENT_LINKED_LIST
|
||||
#define CT331_ASSIGNMENT_LINKED_LIST
|
||||
|
||||
typedef struct listElementStruct listElement;
|
||||
|
||||
//Creates a new linked list element with given content of size
|
||||
//Returns a pointer to the element
|
||||
listElement* createEl(char* data, size_t size);
|
||||
|
||||
//Prints out each element in the list
|
||||
void traverse(listElement* start);
|
||||
|
||||
//Inserts a new element after the given el
|
||||
//Returns the pointer to the new element
|
||||
listElement* insertAfter(listElement* after, char* data, size_t size);
|
||||
|
||||
//Delete the element after the given el
|
||||
void deleteAfter(listElement* after);
|
||||
|
||||
|
||||
// returns the number of elements in the list
|
||||
int length(listElement* list);
|
||||
|
||||
// push a new element onto the head of a list and update the list reference using side effects
|
||||
void push(listElement** list, char* data, size_t size);
|
||||
|
||||
// pop an element from the head of a list and update the list reference using side effects
|
||||
listElement* pop(listElement** list);
|
||||
|
||||
// enque a new element onto the head of the list and update the list reference using side effects
|
||||
void enqueue(listElement** list, char* data, size_t size);
|
||||
|
||||
// dequeue an element from the tail of the list
|
||||
listElement* dequeue(listElement* list);
|
||||
|
||||
#endif
|
Binary file not shown.
@ -0,0 +1,57 @@
|
||||
#include <stdio.h>
|
||||
#include "tests.h"
|
||||
#include "linkedList.h"
|
||||
|
||||
void runTests(){
|
||||
printf("Tests running...\n");
|
||||
|
||||
listElement* l = createEl("Test String (1).", sizeof("Test String (1)."));
|
||||
//printf("%s\n%p\n", l->data, l->next);
|
||||
//Test create and traverse
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
//Test insert after
|
||||
printf("Testing insertAfter()\n");
|
||||
listElement* l2 = insertAfter(l, "another string (2)", sizeof("another test string(2)"));
|
||||
insertAfter(l2, "a final string (3)", sizeof("a final string(3)"));
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
// test length function
|
||||
printf("Testing length()\n");
|
||||
int l_length = length(l);
|
||||
printf("The length of l is %d\n\n", l_length);
|
||||
|
||||
// test push
|
||||
printf("Testing push()\n");
|
||||
push(&l, "yet another test string", sizeof("yet another test string"));
|
||||
traverse(l);
|
||||
printf("\n\n");
|
||||
|
||||
// test pop
|
||||
printf("Testing pop()\n");
|
||||
listElement* popped = pop(&l);
|
||||
traverse(l);
|
||||
printf("\n\n");
|
||||
|
||||
// Test delete after
|
||||
printf("Testing deleteAfter()\n");
|
||||
deleteAfter(l);
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
// test enqueue
|
||||
printf("Testing enqueue()\n");
|
||||
enqueue(&l, "enqueued test string", sizeof("enqueued test string"));
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
// test dequeue
|
||||
printf("Testing dequeue()\n");
|
||||
dequeue(l);
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
printf("\nTests complete.\n");
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#ifndef CT331_ASSIGNMENT_TESTS
|
||||
#define CT331_ASSIGNMENT_TESTS
|
||||
|
||||
void runTests();
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include "genericLinkedList.h"
|
||||
#include "tests.h"
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
runTests();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "genericLinkedList.h"
|
||||
|
||||
typedef struct listElementStruct{
|
||||
void* data;
|
||||
void (*printFunction)(void*);
|
||||
size_t size;
|
||||
struct listElementStruct* next;
|
||||
} listElement;
|
||||
|
||||
//Creates a new linked list element with given content of size
|
||||
//Returns a pointer to the element
|
||||
listElement* createEl(void* data, size_t size, void (*printFunction)(void*)) {
|
||||
listElement* e = malloc(sizeof(listElement));
|
||||
if(e == NULL){
|
||||
//malloc has had an error
|
||||
return NULL; //return NULL to indicate an error.
|
||||
}
|
||||
void* dataPointer = malloc(sizeof(void)*size);
|
||||
if(dataPointer == NULL){
|
||||
//malloc has had an error
|
||||
free(e); //release the previously allocated memory
|
||||
return NULL; //return NULL to indicate an error.
|
||||
}
|
||||
strcpy(dataPointer, data);
|
||||
e->data = dataPointer;
|
||||
|
||||
e->printFunction = printFunction;
|
||||
|
||||
e->size = size;
|
||||
e->next = NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
//Prints out each element in the list
|
||||
void traverse(listElement* start){
|
||||
listElement* current = start;
|
||||
while(current != NULL){
|
||||
current->printFunction(current->data);
|
||||
// printf("%s\n", current->data);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
//Inserts a new element after the given el
|
||||
//Returns the pointer to the new element
|
||||
listElement* insertAfter(listElement* el, void* data, size_t size, void (*printFunction)(void*)){
|
||||
listElement* newEl = createEl(data, size, printFunction);
|
||||
listElement* next = el->next;
|
||||
newEl->next = next;
|
||||
el->next = newEl;
|
||||
return newEl;
|
||||
}
|
||||
|
||||
//Delete the element after the given el
|
||||
void deleteAfter(listElement* after){
|
||||
listElement* delete = after->next;
|
||||
listElement* newNext = delete->next;
|
||||
after->next = newNext;
|
||||
//need to free the memory because we used malloc
|
||||
free(delete->data);
|
||||
free(delete);
|
||||
}
|
||||
|
||||
// returns the number of elements in the list
|
||||
int length(listElement* list) {
|
||||
int length = 0;
|
||||
listElement* current = list;
|
||||
|
||||
// traversing the list and counting each element
|
||||
while(current != NULL){
|
||||
length++;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
// push a new element onto the head of a list and update the list reference using side effects
|
||||
void push(listElement** list, void* data, size_t size, void (*printFunction)(void*)) {
|
||||
// create the new element
|
||||
listElement* newElement = createEl(data, size, printFunction);
|
||||
|
||||
// handle malloc errors
|
||||
if (newElement == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// make the the new element point to the current head of the list
|
||||
newElement->next = *list;
|
||||
|
||||
// make the list reference to point to the new head element
|
||||
*list = newElement;
|
||||
}
|
||||
|
||||
|
||||
// pop an element from the head of a list and update the list reference using side effects
|
||||
// assuming that the desired return value here is the popped element, as is standard for POP operations
|
||||
listElement* pop(listElement** list) {
|
||||
// don't bother if list is non existent
|
||||
if (*list == NULL) { return NULL; }
|
||||
;
|
||||
// getting reference to the element to be popped
|
||||
listElement* poppedElement = *list;
|
||||
|
||||
// make the the second element the new head of the list -- this could be NULL, so the list would be NULL also
|
||||
*list = (*list)->next;
|
||||
|
||||
// detach the popped element from the list
|
||||
poppedElement->next = NULL;
|
||||
|
||||
return poppedElement;
|
||||
}
|
||||
|
||||
|
||||
// enque a new element onto the head of the list and update the list reference using side effects
|
||||
// essentially the same as push
|
||||
void enqueue(listElement** list, void* data, size_t size, void (*printFunction)(void*)) {
|
||||
// create the new element
|
||||
listElement* newElement = createEl(data, size, printFunction);
|
||||
|
||||
// handle malloc errors
|
||||
if (newElement == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// make the the new element point to the current head of the list
|
||||
newElement->next = *list;
|
||||
|
||||
// make the list reference to point to the new head element
|
||||
*list = newElement;
|
||||
}
|
||||
|
||||
|
||||
// dequeue an element from the tail of the list by removing the element from the list via side effects, and returning the removed item
|
||||
// assuming that we want to return the dequeued element rather than the list itself, as enqueue returns nothing and uses side effects, so dequeue should also use side effects
|
||||
listElement* dequeue(listElement* list) {
|
||||
// there are three cases that we must consider: a list with 0 elements, a list with 1 element, & a list with >=2 elements
|
||||
|
||||
// don't bother if list is non existent
|
||||
if (list == NULL) { return NULL; }
|
||||
|
||||
// if there is only one element in the list, i.e. the head element is also the tail element, just returning this element
|
||||
// this means that the listElement pointer that was passed to this function won't be updated
|
||||
// ideally, we would set it to NULL but we can't do that since `list` is a pointer that has been passed by value, so we can't update the pointer itself. we would need a pointer to a pointer to have been passed
|
||||
if (list->next == NULL) {
|
||||
return list;
|
||||
}
|
||||
|
||||
// traversing the list to find the second-to-last element
|
||||
listElement* current = list;
|
||||
while (current->next->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
// get reference to the element to be dequeued
|
||||
listElement* dequeuedElement = current->next;
|
||||
|
||||
// make the penultimate element the tail by removing reference to the old tail
|
||||
current->next = NULL;
|
||||
|
||||
return list;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
#ifndef CT331_ASSIGNMENT_LINKED_LIST
|
||||
#define CT331_ASSIGNMENT_LINKED_LIST
|
||||
|
||||
typedef struct listElementStruct listElement;
|
||||
|
||||
//Creates a new linked list element with given content of size
|
||||
//Returns a pointer to the element
|
||||
listElement* createEl(void* data, size_t size, void (*printFunction)(void*));
|
||||
|
||||
//Prints out each element in the list
|
||||
void traverse(listElement* start);
|
||||
|
||||
//Inserts a new element after the given el
|
||||
//Returns the pointer to the new element
|
||||
listElement* insertAfter(listElement* after, void* data, size_t size, void (*printFunction)(void*));
|
||||
|
||||
//Delete the element after the given el
|
||||
void deleteAfter(listElement* after);
|
||||
|
||||
// returns the number of elements in the list
|
||||
int length(listElement* list);
|
||||
|
||||
// push a new element onto the head of a list and update the list reference using side effects
|
||||
void push(listElement** list, void* data, size_t size, void (*printFunction)(void*));
|
||||
|
||||
// pop an element from the head of a list and update the list reference using side effects
|
||||
listElement* pop(listElement** list);
|
||||
|
||||
// enque a new element onto the head of the list and update the list reference using side effects
|
||||
void enqueue(listElement** list, void* data, size_t size, void (*printFunction)(void*));
|
||||
|
||||
// dequeue an element from the tail of the list
|
||||
listElement* dequeue(listElement* list);
|
||||
|
||||
#endif
|
@ -0,0 +1,79 @@
|
||||
#include <stdio.h>
|
||||
#include "tests.h"
|
||||
#include "genericLinkedList.h"
|
||||
|
||||
// functions to print out different data types
|
||||
// a more professional design might be to put these in the genericLinkedList header file but i only need these for testing purposes
|
||||
void printChar(void* data) {
|
||||
printf("%c\n", *(char*) data);
|
||||
}
|
||||
|
||||
void printStr(void* data) {
|
||||
printf("%s\n", (char*) data);
|
||||
}
|
||||
|
||||
void printInt(void* data) {
|
||||
printf("%d\n", *(int*) data);
|
||||
}
|
||||
|
||||
void runTests(){
|
||||
printf("Tests running...\n");
|
||||
|
||||
listElement* l = createEl("Test String (1).", sizeof("Test String (1)."), printStr);
|
||||
//printf("%s\n%p\n", l->data, l->next);
|
||||
//Test create and traverse
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
//Test insert after
|
||||
printf("Testing insertAfter()\n");
|
||||
listElement* l2 = insertAfter(l, "another string (2)", sizeof("another string (2)"), printStr);
|
||||
insertAfter(l2, "a final string (3)", sizeof("a final string (3)"), printStr);
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
// test length function
|
||||
printf("Testing length()\n");
|
||||
int l_length = length(l);
|
||||
printf("The length of l is %d\n\n", l_length);
|
||||
|
||||
// test push
|
||||
printf("Testing push()\n");
|
||||
push(&l, "yet another test string", sizeof("yet another test string"), printStr);
|
||||
traverse(l);
|
||||
printf("\n\n");
|
||||
|
||||
// test pop
|
||||
printf("Testing pop()\n");
|
||||
listElement* popped = pop(&l);
|
||||
traverse(l);
|
||||
printf("\n\n");
|
||||
|
||||
// Test delete after
|
||||
printf("Testing deleteAfter()\n");
|
||||
deleteAfter(l);
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
// test enqueue
|
||||
printf("Testing enqueue()\n");
|
||||
enqueue(&l, "enqueued test string", sizeof("enqueued test string"), printStr);
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
// test dequeue
|
||||
printf("Testing dequeue()\n");
|
||||
dequeue(l);
|
||||
traverse(l);
|
||||
printf("\n");
|
||||
|
||||
printf("Testing pushing different data types\n");
|
||||
int myint = 42;
|
||||
push(&l, &myint, sizeof(myint), printInt);
|
||||
char mychar = 'c';
|
||||
push(&l, &mychar, sizeof(mychar), printChar);
|
||||
traverse(l);
|
||||
printf("\n\n");
|
||||
|
||||
printf("\nTests complete.\n");
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#ifndef CT331_ASSIGNMENT_TESTS
|
||||
#define CT331_ASSIGNMENT_TESTS
|
||||
|
||||
void runTests();
|
||||
|
||||
#endif
|
Binary file not shown.
Reference in New Issue
Block a user