I would suggest you start with a simple finite array version you can prototype with to make sure everything works as you expect.
Code:
struct Queue {
int data[10];
int front;
int back;
};
void queueInit(struct Queue *q); // Initialise
void queueFini(struct Queue *q); // Cleanup
void queueEnqueue(struct Queue *q, int data); // enqueue a value
void queueDequeue(struct Queue *q, int *data); // dequeue a value
int queueIsEmpty(struct Queue *q); // is it empty?
When that works, then you can do this.
Code:
struct QueueData
{
int data;
struct QueueData *Next;
};
struct Queue {
struct QueueData *front;
struct QueueData *back;
};
void queueInit(struct Queue *q); // Initialise
void queueFini(struct Queue *q); // Cleanup
void queueEnqueue(struct Queue *q, int data); // enqueue a value
void queueDequeue(struct Queue *q, int *data); // dequeue a value
int queueIsEmpty(struct Queue *q); // is it empty?
Notice the interface to the functions does NOT change just because you changed the inside of struct Queue.
So whatever 'main' you had to test the queue functionality with should continue to work when you've changed the implementation.