I am assuming that the item to be inserted in memory is of constant size. If needed, it could be a pointer to a block of memory. In that case, you can use a circular buffer with a head and tail pointer. When either pointer "gets to the end of the block" it should wrap - i.e. you increment / decrement modulo queue size.
Initialization:
Create a memory space of finite size (max size of the buffer)
Add:
Update memory location at the current tail (if add to end)
or head (if add to beginning), and update the tail/head pointer.
Remove:
Read the data at the head/tail, and update the pointer
Peek:
Read the data at the head/tail, and don't move the pointer
Destruct:
Free the memory block
No loops, no recursion. It uses the fact that a FIFO buffer only allows changes at the beginning / end of the queue- it is not possible to remove elements "in the middle".
If the head and tail pointers meet, the queue is "full". In that case, the "insert" function should return an error, unless you add a "insert destructively" flag that says "overwrite the oldest element". That seems beyond the scope of your homework, but it is important in real life applications. Sometimes you care about the oldest data - at other times you care about the latest data. But usually, if your queue is filling up, there is a problem with the over all system design (you didn't scale the process that empties the queue to deal with the rate at which it is filling, basically).
Note - if each element in the queue is a pointer to dynamically allocated memory you WILL need to iterate over all elements to free that memory, or you will create a memory leak. But if the queue is of constant size, this is not needed. Given the constraints given, and the lack of specification that queue element size should be variable, I would recommend you write your solution for a fixed size queue element.
instalationfunction have to do?