Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
master-embedded-systems
c-exercise-solutions public
Commits
4d3a4d79
Commit
4d3a4d79
authored
Aug 24, 2017
by
Dominik Widhalm
Browse files
Added example solutions for task 6.10
parent
45031af5
Changes
2
Hide whitespace changes
Inline
Side-by-side
ch_6/task_10/main.c
0 → 100644
View file @
4d3a4d79
/******************************************************************************
* C PROGRAMMING *
* BASIC EXERCISES - EXAMPLE SOLUTIONS *
* *
* Task_6.10: Priority Queue *
* Author: Dominik Widhalm *
* Email: dominik.widhalm@technikum-wien.at *
* Date: 2017-08-23 *
* *
******************************************************************************/
/***** INCLUDES ***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***** MACROS *****************************************************************/
// Maximum length of strings
#define STRING_MAX 40
// Maximum queue size
#define QUEUE_MAX 10
/***** TYPEDEFS ***************************************************************/
/* Enumeration type for insert & remove return value */
typedef
enum
{
OK
,
EMPTY
,
FULL
,
OLDREMOVED
}
retval_t
;
/* Struct type for the single linked list */
typedef
struct
element
{
// ID
int
id
;
// String
char
string
[
STRING_MAX
];
// priority
int
priority
;
// Pointer to next element
struct
element
*
next
;
}
element_t
;
/***** FUNCTION PROTOTYPES ****************************************************/
retval_t
queue_insert
(
element_t
**
head
,
char
*
string
,
int
priority
);
retval_t
queue_remove
(
element_t
**
head
,
char
*
string
);
void
queue_print
(
element_t
*
head
);
/***** LOCAL FUNCTIONS ********************************************************/
/******************************************************************************
* queue_insert *
* @brief Function to insert a string in the queue. *
* *
* This function first checks if the queue is full. If not, it inserts *
* the given string in the queue (depending on priority). if the queue *
* is already full, the element is only inserted if the new element has *
* a higher priority than one of the elements in the list. In this case *
* the last element is removed. *
* *
* @param head Pointer to pointer to the first queue element *
* @param string Pointer to the desired string *
* @param priority Priority of the new element *
* @retval OK Pushing successful *
* @retval FULL Pushing failed -- stack is full *
* @retval OLDREMOVED Pushing successful, but old element removed *
******************************************************************************/
retval_t
queue_insert
(
element_t
**
head
,
char
*
string
,
int
priority
)
{
/* Temporary pointer to the current queue element */
element_t
*
curr
=
*
head
;
/* Temporary variable for the queue size */
int
size
=
0
;
/* Allocate memory for the new command */
element_t
*
new
=
(
element_t
*
)
malloc
(
sizeof
(
element_t
));
/* Copy the string */
strcpy
(
new
->
string
,
string
);
/* Copy the priority */
new
->
priority
=
priority
;
/* Set the pointers accordingly */
new
->
next
=
NULL
;
/* Retrieve the current queue size */
while
(
curr
!=
NULL
)
{
/* Increase queue size counter */
size
++
;
/* Go to next element */
curr
=
curr
->
next
;
}
/* Check if the list is empty */
if
(
*
head
==
NULL
)
{
/* Add new element as first and only element */
*
head
=
new
;
/* If the list is not empty */
}
else
{
/* Check if new element will be on first position */
if
(
new
->
priority
>
(
*
head
)
->
priority
)
{
/* Next pointer of new element is the current head address */
new
->
next
=
*
head
;
/* Set head to the new element */
*
head
=
new
;
}
else
{
/* Search for the position to add the new entry afterwards */
curr
=
*
head
;
while
(
curr
->
next
!=
NULL
)
{
/* Check if the next element has a greater priority */
if
(
new
->
priority
>
curr
->
next
->
priority
)
{
/* Add new element after this position */
break
;
}
/* Set curr to next element */
curr
=
curr
->
next
;
}
/* Check if found position is last position */
if
(
curr
->
next
==
NULL
)
{
/* Check if list has already reached maximum size */
if
(
size
>=
QUEUE_MAX
)
{
/* Free previously allocated memory */
free
(
new
);
/* Cannot insert, queue already full */
return
FULL
;
}
else
{
/* Set next pointer of currently last element to new element */
curr
->
next
=
new
;
}
/* Otherwise element is somewhere in between */
}
else
{
/* Set the next pointer of the new element to the next element in list */
new
->
next
=
curr
->
next
;
/* Set next pointer of currently last element to new element */
curr
->
next
=
new
;
/* Check if list was already full */
if
(
size
>=
QUEUE_MAX
)
{
/* Temporary pointer to the 2nd last element */
element_t
*
last
=
*
head
;
/* Go to the currently last element */
curr
=
*
head
;
while
(
curr
->
next
!=
NULL
)
{
/* Check if next element is valid element */
if
(
curr
->
next
!=
NULL
)
{
/* Store current address as last one */
last
=
curr
;
}
/* Go to next element */
curr
=
curr
->
next
;
}
/* Remove last element */
last
->
next
=
NULL
;
/* Free allocated memory */
free
(
curr
);
/* Return according status */
return
OLDREMOVED
;
}
}
}
}
/* Inserting successful */
return
OK
;
}
/******************************************************************************
* queue_remove *
* @brief Function to remove a string from the queue. *
* *
* This function first checks if the queue is empty. If not, it returns *
* and removes the next element from the queue. *
* *
* @param head Pointer to pointer to the first queue element *
* @param string Pointer to the read back string *
* @retval OK Removing successful *
* @retval FULL Removing failed -- queue is empty *
******************************************************************************/
retval_t
queue_remove
(
element_t
**
head
,
char
*
string
)
{
/* Temporary pointer to the current queue element */
element_t
*
curr
=
*
head
;
/* Check if queue is empty */
if
(
curr
==
NULL
)
{
/* Queue is empty, cannot remove */
return
EMPTY
;
}
/* Get the string from the current top element */
strcpy
(
string
,
curr
->
string
);
/* Remove first element from the queue */
*
head
=
curr
->
next
;
free
(
curr
);
/* Removing successful */
return
OK
;
}
/******************************************************************************
* queue_print *
* @brief Function to print the current queue. *
* *
* This function prints the current content of the queue (recursively). *
* *
* @param head Pointer to the first stack element *
******************************************************************************/
void
queue_print
(
element_t
*
head
)
{
/* Print list recursively */
if
(
head
!=
NULL
)
{
/* Print current element */
printf
(
"(%d) ->
\"
%s
\"\n
"
,
head
->
priority
,
head
->
string
);
/* Call function with next element */
queue_print
(
head
->
next
);
}
/* A void function has nothing to return */
return
;
}
/***** MAIN ROUTINE ***********************************************************/
int
main
(
void
)
{
/*** Local Variables ***/
element_t
*
head
=
NULL
;
element_t
*
next
;
retval_t
ret
;
char
select
=
'x'
;
char
string
[
STRING_MAX
];
int
priority
;
/* Do as long as the users wants to do an action */
do
{
/* Ask the user to select an action */
printf
(
"
\n
Want do you want to do?
\n
"
);
printf
(
"(i) insert an element
\n
"
);
printf
(
"(r) remove next element
\n
"
);
printf
(
"(p) print current queue
\n
"
);
printf
(
"(x) exit
\n
"
);
printf
(
"Input: "
);
/* Read in the user's input */
scanf
(
" %c"
,
&
select
);
/* Do required action */
switch
(
select
)
{
case
'i'
:
/** Insert a string **/
/* Ask the user to input the command */
printf
(
"Please enter the desired string: "
);
/* Read in the user's input */
scanf
(
"%s"
,
string
);
/* Ask the user to input the priority */
printf
(
"Please enter the desired priority: "
);
/* Read in the user's input */
scanf
(
"%d"
,
&
priority
);
/* (Try to) add the string to the queue */
ret
=
queue_insert
(
&
head
,
string
,
priority
);
if
(
ret
==
FULL
)
{
/* Cannot be added, queue is full */
printf
(
"
\n
FAILED -- QUEUE is already full!
\n
"
);
}
else
if
(
ret
==
OLDREMOVED
)
{
/* Added, but an old element was removed */
printf
(
"
\n
INSERTED -- But an old element was removed!
\n
"
);
}
else
{
/* String has been successfully added */
printf
(
"
\n
INSERTED
\n
"
);
}
/** Finished inserting **/
break
;
case
'r'
:
/** Remove next element **/
/* (Try to) remove the next string from the queue */
if
(
queue_remove
(
&
head
,
string
)
==
EMPTY
)
{
/* Cannot remove, queue is empty */
printf
(
"
\n
FAILED -- Queue is empty!
\n
"
);
}
else
{
/* String has been successfully removed */
printf
(
"
\n
REMOVED:
\"
%s
\"\n
"
,
string
);
}
/** Finished removing **/
break
;
case
'p'
:
/** Print the current queue */
if
(
head
==
NULL
)
{
printf
(
"
\n
... Queue is empty ...
\n
"
);
}
else
{
printf
(
"
\n
... Current queue ...
\n
"
);
queue_print
(
head
);
}
/** Finished printing **/
break
;
}
}
while
(
select
!=
'x'
);
/* Release the allocated memory (use pointer "next" as helper) */
while
(
head
!=
NULL
)
{
/* Save pointer to current element */
next
=
head
;
/* Set head to the next element */
head
=
next
->
next
;
/* Free memory of current element */
free
(
next
);
}
/* Notify the user about the termination of the program */
printf
(
"
\n
The program will now be terminated...
\n
"
);
return
0
;
/* Return with Success (0) */
}
/******************************************************************************/
ch_6/task_10/makefile
0 → 100644
View file @
4d3a4d79
# Get the current path(s) (relevant directory on last position)
TASKPATH
:=
$(
dir
$(
abspath
$(
lastword
$(MAKEFILE_LIST)
)))
CHPATH
:=
$(
dir
$
(
TASKPATH:%/
=
%
))
# Variables for text substitution
empty
:=
slash
:=
/
space
:=
$(empty)
$(empty)
task
:=
task_
ch
:=
ch_
# Get TASK number
TASK
:=
$(
subst
$(slash)
,
$(space)
,
$(TASKPATH)
)
TASK
:=
$(
lastword
$(TASK)
)
TASK
:=
$(
subst
$(task)
,
$(empty)
,
$(TASK)
)
# Get CH number
CH
:=
$(
subst
$(slash)
,
$(space)
,
$(CHPATH)
)
CH
:=
$(
lastword
$(CH)
)
CH
:=
$(
subst
$(ch)
,
$(empty)
,
$(CH)
)
# Specify SRD directory
SRCDIR
=
.
# Call superior makefile
include
../../makefile
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment