The 2 are very similar in implementation, but their subtle differences in usage can make them seem quite different. Here's the short answer:
Ring: intermediate values in the buffer can be read, like a "recent history buffer"
Fifo: only the oldest can be read (and often removed when read)
Long answer
A ring buffer has one pointer that advances and wraps around when it reaches the end.
This permits data to be overwritten when it naturally becomes obsolete. It is useful if you need to keep the last N samples for something. Example usage:
- An FIR implementation, where you would use the most recent N samples. As new data points come in, the FIR would operate on the most recent N data points.
- Capture last N data points if a specific event occurs (like dash cams, that automatically save the last 5 seconds of video if an incident is detected)
A FIFO or Queue (both are one and the same), is often implemented as a ring buffer (templatetypedef's answer is correct, it could be a linked list). In contrast to the ring buffer, there will be 2 pointers; one for read and another for write. Just like the ring buffer pointer, either pointer will wrap around to the beginning of the physical buffer when incremented; giving the illusion of a continuous buffer. Note that it is considered an error for the write pointer to catch up to the read pointer. Example usage:
- One entity is producing data and another is to process it, but the processing can't happen in time or at the same time as the data producer. Like the lineup at the post office.
- messages being sent from one system to another. order is important, and none should be lost.