If you are coming from an object oriented background (as your method signatures seem to indicate).
Object oriented idea -> good way to do it in C
Object creation -> malloc a struct, then pass it into an initialization function
struct queue* q = (struct queue*)malloc(sizeof(struct queue));
queue_initialize(q);
if you want, you can wrap this in a function, like so
struct queue* queue_construct() {
struct queue* q = (struct queue*)malloc(sizeof(struct queue));
queue_initialize(q);
return q;
}
Note that these pointer shouldn't point to void*, let C do at least some of the type checking for you.
Implement a method -> create a function that takes a struct pointer to the "almost this" struct.
struct user* user = ... whatever we do here ...;
queue_add(q, (void*)user);
As far as how to actually implement a queue, I suggest a good data structures or algorithms book, as there are many ways to go about it; and, the specific techniques you choose will have different impacts on performance and reliability. There's no one best way, it depends heavily on how the queue is to be used, and which aspects of performance are more important.
The book I recommend is Introduction to Algorithms. This book is overkill for most situations, with very detailed listings of nearly every major data structure you are likely to encounter in the first few years of programming. As such, it makes a great reference, despite its attempt at a language neutral approach, which now looks odd when compared to common programming languages.
Once you understand what is going on, you can do it in nearly any language.