#include <iostream>
#include <string>
template <typename T, int Capacity>
class StaticStack {
private:
T buffer[Capacity]; // Compile-time fixed array
int top_index; // Index of the *current* top element
public:
// Initialize top_index to -1 (empty state)
StaticStack() : top_index(-1) {}
void push(T val) {
if (top_index >= Capacity - 1) {
std::cout << "Stack Overflow" << std::endl;
return;
}
buffer[++top_index] = val;
}
void pop() {
if (top_index < 0) {
std::cout << "Stack Underflow" << std::endl;
return;
}
top_index--;
}
T peek() const {
if (top_index < 0) {
return T(); // Return default if empty (caller should check)
}
return buffer[top_index];
}
bool isEmpty() const {
return top_index < 0;
}
};
int main() {
// Instantiate a stack of int with capacity 3
StaticStack<int, 3> stack;
int N;
if (!(std::cin >> N)) return 0;
for (int i = 0; i < N; ++i) {
std::string cmd;
std::cin >> cmd;
if (cmd == "PUSH") {
int val;
std::cin >> val;
stack.push(val);
} else if (cmd == "POP") {
stack.pop();
} else if (cmd == "PEEK") {
if (!stack.isEmpty()) {
std::cout << "Top: " << stack.peek() << std::endl;
} else {
std::cout << "Stack Empty" << std::endl; // Matches logic when main checks empty
}
} else if (cmd == "EMPTY") {
std::cout << "Empty: " << (stack.isEmpty() ? "Yes" : "No") << std::endl;
}
}
return 0;
}Explanation & Logic Summary:
Standard C++ containers like std::stack or std::vector use the heap to grow dynamically. In strict embedded environments, we cannot assume heap availability.
int, float, SensorData).int Capacity parameter allows passing a size (like 3) at compile time.StaticStack<int, 3> generates a class with int buffer[3] inside it. The memory is allocated on the stack (or BSS/Data segment if global), ensuring zero fragmentation and predictable RAM usage.Firmware Relevance & Real-World Context:
RingBuffer<uint8_t, 64> is a standard pattern.MenuStack<Screen*, 5>) to allow the "Back" button to work.
Input
6 PUSH 10 PUSH 20 PUSH 30 PUSH 40 PEEK POP
Expected Output
Stack Overflow Top: 30