I'm trying to implement a Double-Linked List ADT in an array (contiguous memory only, no dynamic allocation at runtime). So far, all my code does is generate a seg fault whenever I try and add a new element. Here's the whole ADT, if anybody feels like looking over it.
FILE: CELEMENT.H
/*
* ------------------------------------------------------------------
* Element.h - Element ADT prototypes/data declarations
*
* Author: David McCaughan (1995, CIS2520 revision 2006)
* ------------------------------------------------------------------
*/
#ifndef ELEMENT_H
#define ELEMENT_H
/*
* --- TYPE: Element -------------------------------------------------------
* Component element in 2-way linked data structures
* -------------------------------------------------------------------------
*/
typedef struct Element_t
{
void *data; /* reference to data */
int left; /* reference to index of previous/left element */
int right; /* reference to index of next/right element */
} Element;
/* --- file: Element.c --- */
Element * elementCreate (Element *, void *);
int elementDelete (Element *);
void * elementGetData (Element *);
void * elementSetData (Element *, void *);
int elementGetLeft (Element *);
int elementGetRight (Element *);
void elementSetLeft (Element *, int);
void elementSetRight (Element *, int);
#endif
FILE: CELEMENT.C
/*
* ------------------------------------------------------------------
* Element.c - Element ADT implementation
*
* Author: David McCaughan (1995, CIS*2520 revision 2006)
* ------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include "CElement.h"
/*
* ---------------------------------------------------------
* elementCreate
* - Creates new element, initializing contents to
* be a reference to the provided data
* ---------------------------------------------------------
* PRE:
* n/a
* ---------------------------------------------------------
* POST:
* new element is allocated and initialized; returns a
* reference to the new element
* ---------------------------------------------------------
* ERRORS:
* NULL : memory allocation failure (allocation)
* ---------------------------------------------------------
*/
Element *elementCreate(Element *new, void *data)
{
new->data = data;
return(new);
} /* elementCreate */
/*
* ---------------------------------------------------------
* elementDelete
* - De-allocate memory associated with element
* provided
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* this element is destroyed; returns 0 if this was
* NULL, 1 otherwise
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int elementDelete(Element *this)
{
if (this)
{
this->left=-1;
this->right=-1;
return(1);
}
else
return(0);
} /* elementDelete */
/*
* ---------------------------------------------------------
* elementGetData
* - Obtain reference to the data stored in provided
* element
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns value of data
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
void *elementGetData(Element *this)
{
return(this->data);
} /* elementGetData */
/*
* ---------------------------------------------------------
* elementSetData
* - Reassign reference to the data stored in provided
* element
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns previous (overwritten) value of data
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
void *elementSetData(Element *this, void *data)
{
void *save;
save = this->data;
this->data = data;
return(save);
} /* elementSetData */
/*
* ---------------------------------------------------------
* elementGetLeft
* - Obtain left reference of the provided element
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns value of left
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int elementGetLeft(Element *this)
{
return(this->left);
} /* elementGetLeft */
/*
* ---------------------------------------------------------
* elementGetRight
* - Obtain right reference of the provided element
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns value of right
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int elementGetRight(Element *this)
{
return(this->right);
} /* elementGetRight */
/*
* ---------------------------------------------------------
* elementSetLeft
* - Set left element reference of provided element
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* left is assigned provided reference
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
void elementSetLeft(Element *this, int ref)
{
this->left = ref;
} /* elementSetLeft */
/*
* ---------------------------------------------------------
* elementSetRight
* - Set right element reference of provided element
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* right is assigned provided reference
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
void elementSetRight(Element *this, int ref)
{
this->right = ref;
} /* elementSetRight */
FILE: CLIST.H
/*
* ------------------------------------------------------------------
* List.h - List ADT prototypes/data declarations
*
* Author: David McCaughan (1995, CIS*2520 revision 2006)
* ------------------------------------------------------------------
*/
#ifndef LIST_H
#define LIST_H
#include <stdio.h>
#include "CElement.h"
/*
* --- TYPE: List ----------------------------------------------------------
* A set of objects stored in a 2-way chained linear sequence
* -------------------------------------------------------------------------
*/
typedef struct List_t
{
int element_count; /* number of elements in list */
int position; /* current (numeric) position in list */
Element elements[1000]; /* list of elements */
Element *current; /* current element */
} List;
/* --- file: List.c --- */
List * listCreate (void);
int listDelete (List *);
int listClear (List *);
List * listHead (List *);
List * listTail (List *);
List * listPrev (List *);
List * listNext (List *);
List * listMoveToNth (List *, int);
List * listAddAfter (List *, void *);
List * listAddBefore (List *, void *);
void * listGetCurrent (List *);
void * listSetCurrent (List *, void *);
void * listDelCurrent (List *);
int listIsEmpty (List *);
int listLength (List *);
int listPosition (List *);
#endif
FILE: CLIST.C
/*
* ------------------------------------------------------------------
* List.c - List ADT implementation
*
* Author: David McCaughan (1995, CIS*2520 revision 2006)
* ------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include "CList.h"
#include "CElement.h"
/*
* ---------------------------------------------------------
* listCreate
* - Create new list initialized to empty
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* new list is allocated and initialized; returns a
* reference to new list
* ---------------------------------------------------------
* ERRORS:
* NULL : memory allocation failure (allocation)
* ---------------------------------------------------------
*/
List *listCreate(void)
{
int x=0;
List *new = NULL; /* new list */
if (!(new = calloc(1,sizeof(List))))
return(NULL);
new->element_count = 0;
new->position = 0;
for (x=0; x<1000; x++)
{
new->elements[x].left=-1;
new->elements[x].right=-1;
}
new->current = NULL;
return(new);
} /* listCreate */
/*
* ---------------------------------------------------------
* listDelete
* - De-allocate all memory associated with provided
* list object
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* this list is destroyed; returns number of elements
* that were in the list
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int listDelete(List *this)
{
int retval = 0; /* return value */
if (this)
{
retval = listClear(this);
free(this);
}
return(retval);
} /* listDelete */
/*
* ---------------------------------------------------------
* listClear
* - De-allocate all memory associated with element
* structures of provided list, resetting state of
* list to empty
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* this list is empty; returns number of elements that
* were in the list
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int listClear(List *this)
{
int i; /* loop index */
int retval; /* return value */
/*
* de-allocate element memory
*/
if (this->elements)
{
for (i = 0; i < 1000; i++)
{
this->elements[i].left=-1;
this->elements[i].right=-1;
}
}
/*
* save number of elements in list then reset to empty
*/
this->element_count = 0;
retval = this->element_count;
this->position = 0;
this->current = NULL;
return(retval);
} /* listClear */
/*
* ---------------------------------------------------------
* listHead
* - Adjust position to the beginning of provided list
* - NOTE: this operation is non-destructive on an
* empty list
* ---------------------------------------------------------
* PRE:
* list is non-empty
* ---------------------------------------------------------
* POST:
* current & position reference the first element in
* this list; returns a reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* ---------------------------------------------------------
*/
List *listHead(List *this)
{
if (this->elements != NULL)
{
this->current = &this->elements[0];
this->position = 1;
return(this);
}
else
return(NULL);
} /* listHead */
/*
* ---------------------------------------------------------
* listTail
* - Adjust position to the end of provided list
* - NOTE: this operation is non-destructive on an
* empty list
* ---------------------------------------------------------
* PRE:
* list is non-empty
* ---------------------------------------------------------
* POST:
* current & position reference the last element in
* this list; returns a reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* ---------------------------------------------------------
*/
List *listTail(List *this)
{
if (this->elements != NULL)
{
this->current = &this->elements[elementGetLeft(this->elements)];
this->position = this->element_count;
return(this);
}
else
return(NULL);
} /* listTail */
/*
* ---------------------------------------------------------
* listPrev
* - Move the the previous element in the provided list
* ---------------------------------------------------------
* PRE:
* list is non-empty; list is not positioned at the
* first element
* ---------------------------------------------------------
* POST:
* current & postition now reference the element
* preceeding the current one in this list; returns a
* reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* NULL : already at beginning of list
* ---------------------------------------------------------
*/
List *listPrev(List *this)
{
/*
* note that this explicity covers "at beginning of list", and
* implicitly covers "empty list", and "single element list" cases.
*/
if (this->current == &this->elements[0])
return(NULL);
this->current = &this->elements[elementGetLeft(this->current)];
this->position--;
return(this);
} /* listPrev */
/*
* ---------------------------------------------------------
* listNext
* - Move the the next element in the provided list
* ---------------------------------------------------------
* PRE:
* list is non-empty; list is not positioned at the
* last element
* ---------------------------------------------------------
* POST:
* current & position now reference the element
* succeeding the current one in this list; returns
* a reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* NULL : already at end of list
* ---------------------------------------------------------
*/
List *listNext(List *this)
{
/*
* must explicitly cover "at end of list" as well as "empty list"
* and "single element list" cases
*/
if ((this->position >= this->element_count)
|| (!this->elements) || (this->element_count < 2))
return(NULL);
this->current = &this->elements[elementGetRight(this->current)];
this->position++;
return(this);
} /* listNext */
/*
* ---------------------------------------------------------
* listMoveToNth
* - Move to the "Nth" element in the provide dlist
* - NOTE: elements are counted from 1 (not 0)
* ---------------------------------------------------------
* PRE:
* 0 < n <= element_count
* ---------------------------------------------------------
* POST:
* current & position now reference the "Nth" element
* in this list; returns a reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : element index out of bounds (index)
* ---------------------------------------------------------
*/
List *listMoveToNth(List *this, int n)
{
int i; /* loop index */
int offset; /* offset to new location from current */
int ofor; /* forward and ... */
int obak; /* ... backward offsets respectively */
/*
* this should avoid ANY illegal situation (i.e. an "nth" element
* exists) - excepting destructive user interference
*/
if ((n < 1) || (n > this->element_count))
return(NULL);
/*
* determine offset & direction of pointer movement from current:
* (adds a couple of arithmetic operations over linear search
* however may save time if movement is highly localized or a
* regular progression through the list (i.e. by 2s))
*/
obak = (this->position - n + this->element_count) % this->element_count;
ofor = (n - this->position + this->element_count) % this->element_count;
offset = (obak < ofor) ? obak : ofor;
if (ofor < obak)
/* move forward */
for (i = 0; i < offset; i++)
this->current = &this->elements[elementGetRight(this->current)];
else
/* move backward */
for (i = 0; i < offset; i++)
this->current = &this->elements[elementGetLeft(this->current)];
this->position = n;
return(this);
} /* listMoveToNth */
/*
* ---------------------------------------------------------
* listAddAfter
* - Insert a new element containing the provided
* data reference in list AFTER current element
* - NOTE: current reference remains unchanged
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* element containing data reference is inserted into
* this list AFTER the current one, or is installed as
* the new head of the list if it was emtpy; returns
* a reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : new_element() failure
* ---------------------------------------------------------
*/
List *listAddAfter(List *this, void *data)
{
int x;
Element *new; /* new element */
if (!(new = elementCreate(new, data)))
return(NULL);
/*
* link into list
*/
if (!this->elements)
{
this->elements[0] = *new;
this->current = this->elements;
elementSetLeft(this->current,0);
elementSetRight(this->current,0);
this->position++;
}
else
{
for (x=0; x<1000; x++){
if ((this->elements[x].left==-1)&&(this->elements[x].right==-1))
{
this->elements[x]=*new;
break;
}
}
elementSetLeft(new, elementGetLeft(&this->elements[(elementGetRight(this->current))]));
elementSetLeft(&this->elements[elementGetRight(this->current)],x);
elementSetRight(new,elementGetRight(this->current));
elementSetRight(this->current,x);
}
this->element_count++;
return(this);
} /* listAddAfter */
/*
* ---------------------------------------------------------
* listAddBefore
* - Insert a new element containing the provided
* data reference in list BEFORE current element
* - NOTE: current reference remains unchanged
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* element containing data reference is inserted into
* this list BEFORE the current one, or is installed as
* the new head of the list if it was emtpy; returns
* a reference to this
* ---------------------------------------------------------
* ERRORS:
* NULL : new_element() failure
* ---------------------------------------------------------
*/
List *listAddBefore(List *this, void *data)
{
int x;
Element *new; /* new element */
if (!(new = elementCreate(new, data)))
return(NULL);
/*
* link into list
*/
if (!this->elements)
{
this->elements[0] = *new;
this->current = this->elements;
elementSetLeft(this->current,0);
elementSetRight(this->current,0);
this->position++;
}
else
{
for (x=0; x<1000; x++){
if ((this->elements[x].left==-1)&&(this->elements[x].right==-1))
{
this->elements[x]=*new;
break;
}
}
elementSetRight(new, elementGetLeft(&this->elements[(elementGetRight(this->current))]));
elementSetRight(&this->elements[elementGetLeft(this->current)],x);
elementSetLeft(new,elementGetLeft(this->current));
elementSetLeft(this->current,x);
/*
* must adjust head of list if addition is at front of list
*/
if (this->current == &this->elements[0])
this->elements[0] = *new;
}
this->element_count++;
this->position++;
return(this);
} /* listAddBefore */
/*
* ---------------------------------------------------------
* listGetCurrent
* - Obtain a reference to data from the current
* element data in the provided list
* ---------------------------------------------------------
* PRE:
* list is non-empty
* ---------------------------------------------------------
* POST:
* returns a reference to the data in the current
* element in this list
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* ---------------------------------------------------------
*/
void *listGetCurrent(List *this)
{
if (!this->elements)
return(NULL);
return(elementGetData(this->current));
} /* listGetCurrent */
/*
* ---------------------------------------------------------
* listSetCurrent
* - Reassign a data reference within the current
* element of the provided list
* ---------------------------------------------------------
* PRE:
* list is non-empty
* ---------------------------------------------------------
* POST:
* returns a reference to the previous (overwritten)
* data in the current element of this list
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* ---------------------------------------------------------
*/
void *listSetCurrent(List *this, void *data)
{
void *dval; /* reference to data value */
if (!this->elements)
return(NULL);
dval = elementGetData(this->current);
elementSetData(this->current,data);
return(dval);
} /* listSetCurrent */
/*
* ---------------------------------------------------------
* listDelCurrent
* - Remove current element from the provided list and
* obtain a reference to the data in the element
* ---------------------------------------------------------
* PRE:
* list is non-empty
* ---------------------------------------------------------
* POST:
* returns a reference to the data in the current
* element in this list which no longer occurs in
* the list; new current element is removed's
* successor
* ---------------------------------------------------------
* ERRORS:
* NULL : list is empty
* ---------------------------------------------------------
*/
void *listDelCurrent(List *this)
{
Element *el; /* reference to item to be deleted */
void *dval; /* reference to data value */
if (!this->elements)
return(0);
/*
* note element for deletion
*/
el = this->current;
/*
* re-link list to remove current node
*/
elementSetRight(&this->elements[elementGetLeft(this->current)], elementGetRight(this->current));
elementSetLeft(&this->elements[elementGetRight(this->current)], elementGetLeft(this->current));
this->current = &this->elements[elementGetRight(this->current)];
/*
* SPECIAL CASES:
*/
/* single element list - deleting only item */
if (this->element_count == 1)
{
listClear(this);
}
/* end node removed - wrapping current to first */
else if (&this->elements[0] == this->current)
this->position = 1;
/* first node removed - updating head of list */
else if (&this->elements[0] == el)
this->elements[0] = *this->current;
this->element_count--;
dval = elementGetData(el);
elementDelete(el);
return(dval);
} /* listDelCurrent */
/*
* ---------------------------------------------------------
* listIsEmpty
* - Determine if provided list is empty
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns 1 if this is empty, 0 otherwise
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int listIsEmpty(List *this)
{
return(this->element_count == 0);
} /* listIsEmpty */
/*
* ---------------------------------------------------------
* listLength
* - Determine number of elements (length) in
* provided list
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns value of element_count
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int listLength(List *this)
{
return(this->element_count);
} /* listLength */
/*
* ---------------------------------------------------------
* listPosition
* - Obtain numeric value of current position in
* provided list
* ---------------------------------------------------------
* PRE:
* void
* ---------------------------------------------------------
* POST:
* returns value of position
* ---------------------------------------------------------
* ERRORS:
* void
* ---------------------------------------------------------
*/
int listPosition(List *this)
{
return(this->position);
} /* listPosition */
FILE: LISTMENU.C
/* === TESTING LIST TYPE === */
#include <stdlib.h>
#include <stdio.h>
#include "List.h"
#define BUFSIZE 81
struct etype
{
int key;
char str[10];
};
int main()
{
List *tst;
int opt, misc, savepos;
char dummy[BUFSIZE];
struct etype *el, *rel;
if (!(tst = listCreate()))
exit(-1);
while(1)
{
printf("\n\n\nList (<ctrl-C> to quit):\n");
printf("1 - listClear()\n");
printf("2 - listHead()\n");
printf("3 - listTail()\n");
printf("4 - listPrev()\n");
printf("5 - listNext()\n");
printf("6 - listMoveToNth()\n");
printf("7 - listAddAfter()\n");
printf("8 - listAddBefore()\n");
printf("9 - listGetCurrent()\n");
printf("10 - listSetCurrent()\n");
printf("11 - listDelCurrent()\n");
printf("12 - listIsEmpty()\n");
printf("13 - listLength()\n");
printf("14 - listPosition()\n");
printf("\n");
printf("CHOICE: ");
gets(dummy);
sscanf(dummy,"%d",&opt);
switch(opt)
{
case 1:
if ((misc = listClear(tst)) < 0)
{
fprintf(stderr,"listClear error\n");
exit(-1);
}
else
printf("\nList of size %d cleared\n",misc);
break;
case 2:
if (!listHead(tst))
fprintf(stderr,"\n>>> NO MOVEMENT - List is empty\n");
break;
case 3:
if (!listTail(tst))
fprintf(stderr,"\n>>> NO MOVEMENT - List is empty\n");
break;
case 4:
if (!listPrev(tst))
fprintf(stderr,"\n>>> List empty, or already at beginning\n");
break;
case 5:
if (!listNext(tst))
fprintf(stderr,"\n>>> List empty, or already at end\n");
break;
case 6:
printf("\nMove to (n > 0): ");
gets(dummy);
sscanf(dummy,"%d",&misc);
if (!listMoveToNth(tst,misc))
fprintf(stderr,"\n>>> List empty, or element %d out of range\n",misc);
break;
case 7:
el = malloc(sizeof(struct etype));
printf("\nKEY(int) : ");
gets(dummy);
sscanf(dummy,"%d", &el->key);
printf("STRING(char *) : ");
gets(el->str);
if (!listAddAfter(tst,el))
{
fprintf(stderr,"listAddAfter error\n");
exit(-1);
}
break;
case 8:
el = malloc(sizeof(struct etype));
printf("\nKEY(int) : ");
gets(dummy);
sscanf(dummy,"%d", &el->key);
printf("STRING(char *) : ");
gets(el->str);
if (!listAddBefore(tst,el))
{
fprintf(stderr,"listAddBefore error\n");
exit(-1);
}
break;
case 9:
if (!(rel = (struct etype *)listGetCurrent(tst)))
fprintf(stderr,"\n>>> List is empty\n");
else
printf("\nELEMENT : Key: %d\n Str: %s\n",rel->key, rel->str);
break;
case 10:
el = malloc(sizeof(struct etype));
printf("\nKEY(int) : ");
gets(dummy);
sscanf(dummy,"%d", &el->key);
printf("STRING(char *) : ");
gets(el->str);
if (!(rel = listSetCurrent(tst,el)))
{
fprintf(stderr,"listSetCurrent error\n");
exit(-1);
}
free(rel);
break;
case 11:
if (!(rel = (struct etype *)listDelCurrent(tst)))
fprintf(stderr,"\n>>> NO DELETION : List is empty\n");
else
{
printf("\nELEMENT : Key: %d\n Str: %s\n",rel->key, rel->str);
free(rel);
}
break;
case 12:
printf("\nList is %s\n",(listIsEmpty(tst) ? "empty" : "non-empty"));
break;
case 13:
printf("\nSize of list : %d\n",listLength(tst));
break;
case 14:
printf("\nPosition : %d\n",listPosition(tst));
break;
default:
printf("\n>>> ILLEGAL SELECTION\n");
break;
}
printf("\n============\n\n");
printf("NEW (CURRENT) STATE:\n");
savepos = listPosition(tst);
listHead(tst);
if (listIsEmpty(tst))
printf("List is empty\n");
else
{
do
{
el = listGetCurrent(tst);
if (savepos == listPosition(tst))
{
printf("*>");
printf("[%d|%s]",el->key, el-> str);
printf("<* ");
}
else
printf("[%d|%s] ",el->key, el-> str);
} while(listNext(tst));
printf("\n");
}
listMoveToNth(tst,savepos);
printf("\nHit <enter>...\n");
gets(dummy);
}
listDelete(tst);
}
MAKEFILE
CC = gcc
CFLAGS = -Wall -ansi -pedantic
LDFLAGS =
INCLUDES =
LIBDIRS =
LIBS =
LISTOBJS = \
CList.o\
CElement.o\
ListMenu.o
default : all
all : CListMenu
CListMenu : $(LISTOBJS)
$(CC) $(LIBDIRS) $(LDFLAGS) -o $@ $(LISTOBJS) $(LIBS)
Element.o: Element.c Element.h
$(CC) $(CFLAGS) -c Element.c $(INCLUDES)
List.o: List.c List.h Element.h
$(CC) $(CFLAGS) -c List.c $(INCLUDES)
CElement.o: CElement.c CElement.h
$(CC) $(CFLAGS) -c CElement.c $(INCLUDES)
CList.o: CList.c CList.h CElement.h
$(CC) $(CFLAGS) -c CList.c $(INCLUDES)
ListMenu.o: ListMenu.c List.h Element.h
$(CC) $(CFLAGS) -c ListMenu.c $(INCLUDES)
clean:
@ rm *.o