Data Structures
Circular Queue
A fixed-size queue can wrap its head and tail indexes around the array.
tail wrap
Modulo arithmetic moves the tail back to zero after the final slot.
first out
Reading from the head removes the oldest queued value first.
Circular Queue
circular_queue.c
Replay: real traced execution (multi-file project)
#include <stdio.h>
int main(void) {
int count = 3;
int queue[4] = {0, 0, 0, 0};
int head = 0;
int tail = 0;
for (int i = 0; i < count; i++) {
queue[tail] = (i + 1) * 10;
tail = (tail + 1) % 4;
}
int first = queue[head];
head = (head + 1) % 4;
int second = queue[head];
printf("first=%d second=%d tail=%d\n", first, second, tail);
return 0;
}
#include <stdio.h>
int main(void) {
int count = 2;
int queue[4] = {0, 0, 0, 0};
int head = 0;
int tail = 0;
for (int i = 0; i < count; i++) {
queue[tail] = (i + 1) * 10;
tail = (tail + 1) % 4;
}
int first = queue[head];
head = (head + 1) % 4;
int second = queue[head];
printf("first=%d second=%d tail=%d\n", first, second, tail);
return 0;
}
#include <stdio.h>
int main(void) {
int count = 4;
int queue[4] = {0, 0, 0, 0};
int head = 0;
int tail = 0;
for (int i = 0; i < count; i++) {
queue[tail] = (i + 1) * 10;
tail = (tail + 1) % 4;
}
int first = queue[head];
head = (head + 1) % 4;
int second = queue[head];
printf("first=%d second=%d tail=%d\n", first, second, tail);
return 0;
}
count ← 3, queue ← ⟨addr A⟩, head ← 0, tail ← 0
3int main(void) {4 int count→ 3 = 3; //@count=2, 45 int queue→ ⟨addr A⟩[4] = {0, 0, 0, 0};6 int head→ 0 = 0;7 int tail→ 0 = 0;queue[tail] ← 10, tail ← 1
pass 1 of 39for (int i0 = 0; i < count3; i++) {10 queue[tail]→ 10 = (i0 + 1) * 10;11 tail→ 1 = (tail + 1) % 4;12}All 3 passes — pass 1 is the card above pass iqueue[tail]tail1 0 0 → 10 0 → 1 2 1 0 → 20 1 → 2 3 2 0 → 30 2 → 3 first ← 10, head ← 1, second ← 20
14 int first→ 10 = queue[head]10;15 head→ 1 = (head + 1) % 4;16 int second→ 20 = queue[head]20;1718 printf("first=%d second=%d tail=%d\n", first10, second20, tail3);19 return 0;20}outputfirst=10 second=20 tail=3
count ← 2, queue ← ⟨addr A⟩, head ← 0, tail ← 0
3int main(void) {4 int count→ 2 = 2;5 int queue→ ⟨addr A⟩[4] = {0, 0, 0, 0};6 int head→ 0 = 0;7 int tail→ 0 = 0;queue[tail] ← 10, tail ← 1
pass 1 of 29for (int i0 = 0; i < count2; i++) {10 queue[tail]→ 10 = (i0 + 1) * 10;11 tail→ 1 = (tail + 1) % 4;12}queue[tail] ← 20, tail ← 2
pass 2 of 29for (int i1 = 0; i < count2; i++) {10 queue[tail]→ 20 = (i1 + 1) * 10;11 tail→ 2 = (tail + 1) % 4;12}first ← 10, head ← 1, second ← 20
14 int first→ 10 = queue[head]10;15 head→ 1 = (head + 1) % 4;16 int second→ 20 = queue[head]20;1718 printf("first=%d second=%d tail=%d\n", first10, second20, tail2);19 return 0;20}outputfirst=10 second=20 tail=2
count ← 4, queue ← ⟨addr A⟩, head ← 0, tail ← 0
3int main(void) {4 int count→ 4 = 4;5 int queue→ ⟨addr A⟩[4] = {0, 0, 0, 0};6 int head→ 0 = 0;7 int tail→ 0 = 0;queue[tail] ← 10, tail ← 1
pass 1 of 49for (int i0 = 0; i < count4; i++) {10 queue[tail]→ 10 = (i0 + 1) * 10;11 tail→ 1 = (tail + 1) % 4;12}All 4 passes — pass 1 is the card above pass iqueue[tail]tail1 0 0 → 10 0 → 1 2 1 0 → 20 1 → 2 3 2 0 → 30 2 → 3 4 3 0 → 40 3 → 0 first ← 10, head ← 1, second ← 20
14 int first→ 10 = queue[head]10;15 head→ 1 = (head + 1) % 4;16 int second→ 20 = queue[head]20;1718 printf("first=%d second=%d tail=%d\n", first10, second20, tail0);19 return 0;20}outputfirst=10 second=20 tail=0