#include<iostream.h>
#include<string.h>
#include<stdlib.h>
const int MAX=100;
 class stackexp //栈异常类
{
 public:
   virtual void print(void)=0;
};
 class stackemp:public stackexp
{
 public:
   void print(void);
};
 class stackful:public stackexp
{
 public:
   void print(void);
};
void stackemp::print(void)
{
 cout<<"栈已空!"<<endl;
}
void stackful::print(void)
{
 cout<<"栈已满!"<<endl;
}
 template <class T>
 class stack  //栈类模板
{
 public:
   stack(void);
   ~stack();
   T pop(void);
   void push(T x);
   int s_empty(void);
   int s_full(void);
 private:
   T s[MAX];
   int top;
};
template <class T>
 stack<T>::stack(void)
{
  top=-1;
  cout<<"创建了一个栈"<<endl;
}
 template <class T>
 stack<T>::~stack()
{
  cout<<"栈消失"<<endl;
}
 template <class T>
 T stack<T>::pop(void)
{
  if(top==-1)
   throw &stackemp();
  return(s[top--]);
}
 template <class T>
 void stack<T>::push(T x)
{
  if(top==MAX-1)
   throw &stackful();
  s[++top]=x;
}
 template <class T> 
 int stack<T>::s_empty(void)
{
 int flag;
 flag=top==-1?1:0;
 return(flag);  
}
 template <class T> 
 int stack<T>::s_full(void)
{
 int flag;
 flag=top==MAX-1?1:0;
 return(flag);
}
 class cal   //计算器类
{
 public:
  void run(void); //运行计算器
  void clear(void); //清空操作数栈
 private:
  stack<float> s;  //操作数栈
  bool out(float& op1,float& op2);//连续将两个操作数弹出栈
  void go(char op); //执行由操作符op指定的运算
};
bool cal::out(float& op1,float& op2)
{
  if(s.s_empty()==1) 
 {
   cout<<"没有操作数！"<<endl;
   return false;
 }
  op1=s.pop();//将右操作数弹出栈
  if(s.s_empty()==1) 
 {
   cout<<"没有操作数！"<<endl;
   return false;
 }
  op2=s.pop(); //将左操作数弹出栈
  return true;
}
void cal::go(char op)
{
  bool flag;
  float op1,op2,result;
  flag=out(op1,op2);
  if(flag==true)//成功则执行运算,并将结果压入栈
  {
   switch(op)
   {
    case '+': result=op2+op1;break;
    case '-': result=op2-op1;break;
    case '*': result=op2*op1;break;
    case '/': result=op2/op1;
   }
   s.push(result);
   cout<<"="<<result<<" ";//输出本次运算结果		        
  }
  else
   clear();
}
 void cal::run(void)
{
 char c[10];
 cin>>c;
 while(strcmp(c,"q")!=0)//遇字符q结束
 {
  switch(*c)
  {
   case 'c':clear();break;//遇字符c清空栈
   case '+':  //遇操作符则执行运算         
   case '*':
   case '/': 
   case '-':  if(strlen(c)==1) 
             {
			  go(*c);     //执行计算
              break;
			 }
   default: s.push(atof(c));//若读入的是操作数，压入栈
  }
  cin>>c;
 }
}
 void cal::clear(void)// 清空操作数栈
{
  while(s.s_empty==0)
   s.pop();
}
 int main()
{
 cal t;
 t.run();
 return(0);
}
