栈的原理
栈是函数实现返回的原理。
按符号的优先级压入栈,全部完毕后按“先进后出,后进先出”的顺序出栈并计算。
栈类模板
第一部分:栈类模板
// Stack.h
#ifndef STACK_H
#define STACK_H
#include <cassert>
template <class T, int SIZE = 50>
class Stack {
private:
T list[SIZE];
int top;
public:
Stack();
void push(const T& item);
T pop();
void clear();
const T& peek() const; //只读函数写成常函数
bool isEmpty() const;
bool isFull() const;
};
//模板的实现
template <class T, int SIZE>
Stack<T, SIZE>::Stack() : top(-1) { }
template <class T, int SIZE>
void Stack<T, SIZE>::push(const T& item) {
assert(!isFull()); //<cassert>头文件
list[++top] = item; //栈的核心点,时刻用top来控制
}
template <class T, int SIZE>
T Stack<T, SIZE>::pop() {
assert(!isEmpty());
return list[top--];
}
template <class T, int SIZE>
const T& Stack<T, SIZE>::peek() const {
assert(!isEmpty());
return list[top]; //返回栈顶元素
}
template <class T, int SIZE>
bool Stack<T, SIZE>::isEmpty() const {
return top == -1;
}
template <class T, int SIZE>
bool Stack<T, SIZE>::isFull() const {
return top == SIZE - 1;
}
template <class T, int SIZE>
void Stack<T, SIZE>::clear() {
top = -1;
}
#endif //STACK_H
第二部分: Calculator类 .h文件
//Calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include "Stack.h"
class Calculator {
private:
Stack<double> s; //操作数栈,先创建栈类的对象
void enter(double num);
bool getTwoOperands(double& oped1, double& oped2);
void compute(char op);
public:
void run();
void clear();
};
#endif // !CALCULATOR_H
第三部分: Calculator类实现部分,注意是cpp文件
// Calculator.cpp
#include <iostream>
#include "Calculator.h"
#include <sstream>
#include <cmath>
using namespace std;
inline double stringToDouble(const string& str) {
istringstream stream(str);
double result;
stream >> result;
return result;
}
void Calculator::enter(double num) {
s.push(num);
}
bool Calculator::getTwoOperands(double& oped1, double& oped2) {
//该函数的目的是把栈顶的值依次赋给oped1,oped2,用传递引用的方式巧妙解决返回多值
//返回一个bool值,通过是否成功返回值来判断能不能进行运算
if (s.isEmpty()) {
cerr << "缺少参数:" << endl;
return false;
}
oped1 = s.pop();
if (s.isEmpty()) {
cerr << "缺少参数:" << endl;
return false;
}
oped2 = s.pop();
return true;
}
void Calculator::compute(char op) {
double operand1, operand2;
bool result = getTwoOperands(operand1, operand2);
if (result) {
switch (op) {
case '+': s.push(operand2 + operand1); break;
case '-': s.push(operand2 - operand1); break;
case '*': s.push(operand2 * operand1); break;
case '/':
//除法运算要考虑除数为0的情况
if (operand1 == 0) {
cerr << "除数不能为0 " << endl;
s.clear();
}
else
s.push(operand2 / operand1); break;
case '^': s.push(pow(operand2, operand1)); break;
default: cerr << "不能识别该操作数" << endl; break;
}
cout << "= " << s.peek() << " ";
}
else
s.clear();
}
void Calculator::run() {
string str;
while (cin >> str, str != "q") { //能够持续读入,判断条件是逗号后面的内容
switch (str[0])
{
case 'c': s.clear(); break;
case '-':
if (str.size() > 1)
enter(stringToDouble(str));
else
compute(str[0]);
break; //break非常重要
case '+':
case '*':
case '/':
case '^':
compute(str[0]); break;
default:
enter(stringToDouble(str)); break;
}
}
}
void Calculator::clear() {
s.clear();
}
第四部分: 主程序,只用include"Calculator.h"即可,Calculator的cpp文件可以单独写
#include "Calculator.h"
int main() {
Calculator c;
c.run();
return 0;
}
switch case用法
case不加break
switch语句原理是跳转到caseX位置执行剩下所有的语句(包括其他case里面的),直到最后或者遇见break为止。因此在每一条语句最后+break即可。
因此不加break的话将会执行跳转到的case本身以及以下所有的语句。