栈的应用——一个简单的整数计算器

实现一个简单的整数计算器,能够进行加、减、乘、除和乘方运算。使用时算式采用后缀输入法,每个操作数、操作符之间都以空白符分隔。乘方运算用“^”表示。每次运算在前次结果基础上进行,若要将前次运行结果清除,可键入“c”。当键入“q”时程序结束。

//stack.h

#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;

enum Boolean {false,true};
const int MaxStackSize=50; //栈的大小,即栈中元素的最大个数

template <class T>
class Stack
{
private:
   T stacklist[MaxStackSize]; //数组,用于存放栈的元素
   int top;               //栈顶位置(数组下标)
public:
   Stack(void);         //构造函数,初始化栈
   void Push(const T& item); //将元素item压入栈
   T Pop(void);             //将栈顶元素弹出栈
   void ClearStack(void);  //将栈清空
   T peek(void) const;   //访问栈顶元素
  
   int StackEmpty(void) const;  //测试是否栈空
   int StackFull(void) const;   //测试是否栈满
};
template<class T>
Stack<T>::Stack(void):top(-1)  //构造函数,栈顶初始化为-1
{}

template<class T>
void Stack<T>::Push(const T& item) //将元素item压入栈
{
    if(top==MaxStackSize-1)
    {
    std::cerr<<"Stack overflow!"<<endl;
    exit(1);
    }
    top++;
    stacklist[top]=item;
}

template<class T>
T Stack<T>::Pop(void)     //将栈顶元素弹出栈
{
    T temp;
    if(top==-1)
    {
   std::cerr<<"Attempting to pop an empty stck!"<<endl;
   exit(1);
 }
 temp=stacklist[top];
    top--;
    return temp;
}

template<class T>
T Stack<T>::peek(void) const  //访问栈顶元素
{
  if(top==-1)
  {
   std::cerr<<"Attempting to peek at an empty stack!"<<endl;
   exit(1);
  }
  return stacklist[top];
}

template<class T>
int Stack<T>::StackEmpty(void) const  //测试栈是否空
{
   return top==-1;
}

template<class T>
int Stack<T>::StackFull(void) const  //测试栈是否满
{
   return top=MaxStackSize-1;
}

template<class T>
void Stack<T>::ClearStack(void)
{
  top=-1;
}

//calculator.h

class Calculator   //计算器类
{
private:
    Stack <int> S;  //操作数栈
 void Enter(int num);//将操作数num压入栈
 //连续将两个 操作数弹出栈,放在opnd1和opnd2中
 Boolean GetTwoOperands(int& opnd1,int& opnd2);
 void Compute(char op);  //执行由操作符op指定的运算
public:
    Calculator(void);   //构造函数
 void Run(void);    //运行计算器程序
 void Clear(void);  //清空操作数栈
};
void Calculator::Enter(int num)
{
   S.Push(num);
}
Boolean Calculator::GetTwoOperands(int& opnd1,int& opnd2)
{
   if(S.StackEmpty())
   {
     cerr<<"Missing operand!"<<endl;
     return false;
   }
   opnd1=S.Pop();
    if(S.StackEmpty())
   {
     cerr<<"Missing operand!"<<endl;
     return False;
   }
   opnd2=S.Pop();
   return true;
}

void Calculator::Compute(char op)
{
   Boolean result;
   int operand1,operand2;
   result=GetTwoOperands(operand1,operand2);
   if(result==True)
   {
      switch(op)
      {
     case '+':  S.Push(operand2+operand1);
                   break;
        case '-':  S.Push(operand2-operand1);
                   break;
        case '*':  S.Push(operand2*operand1);
                   break;
        case '/':  if(operand1==0)
                   {
         cerr<<"Divide by 0!"<<endl;
         S.ClearStack();
       }
       else
         S.Push(operand2/operand1);
                     break;
         case '^': S.Push(pow(operand2,operand1));
                   break;
      }
      cout<<'='<<S.peek()<<' ';
   }
   else
      S.ClearStack();
}
Calculator::Calculator(void)
{}
void Calculator::Run(void)
{
  char c[20];
  while(cin>>c,*c!='q')  //读入表达式,遇'q'结束
    switch(*c)
    {
 case 'c': S.ClearStack();  //遇'c'清空操作数栈
            break;
    case '-':
             if(strlen(c)>1)
              Enter(atoi(c));//将字符串转换为整数,压入栈
             else
              Compute(*c);
             break;
    case '+':
    case '*':
    case '/':
    case '^':
             Compute(*c);
             break;
    default:                         //若读入的是操作数,转换为整型后压入栈
             Enter(atoi(c));
             break;
 }
}  
void Calculator::Clear(void)
{
  S.ClearStack();
}

//主函数

#include"stack.h"
#include"calculator.h"

 

int main()
{
  Calculator CALC;
  CALC.Run();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一小部分代码 请参考 org 0000h jmp start ;Start of the program org 0100h start: mov A,#030h ;1 line, 8 bits call wrcmd mov A,#LCD_SETVISIBLE + 4 call wrcmd mov A,#LCD_SETDDADDR+15 ; Start at right hand side of the display call wrcmd mov A,#LCD_SETMODE + 3 ; Automatic Increment - Display shift left. call wrcmd mov 025h,#00h ; Set output mode (floating point). call boundsbuffer ; Initialise the bounds buffer - used for error checking. mov mode,#4 ; Initialise the constant buffer to 100. Primarily used for % ops. mov digitcode,#031h call storedigit mov digitcode,#030h call storedigit mov digitcode,#030h call storedigit mov status,#00h ; variable used to determine the first key press after an operation. mov bufferctr,#00h mov opcounter,#00h mov decimalcnt,#00h call waitkey halt: mov PCON,#1 ;Halt ;*********************************************************** ;**** Floating Point Package **** ;******************************** $INCLUDE (FP52.ASM) ;Routine to peek arg at DPTR argout: mov R0,#FP_NUMBER_SIZE aoloop: movx A,@DPTR anl A,#0F0h rr a rr a rr a rr a add A,#aodata-$-3 movc A,@A+PC call sndchr movx A,@DPTR anl A,#0Fh add A,#aodata-$-3 movc A,@A+PC call sndchr inc DPTR djnz R0, aoloop ret aodata: db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' ;Routine to output character in A, preserving all but A. sndchr: push R0B0 push R1B0 call getmode mov digitcode,A call storedigit pop R1B0 pop R0B0 ret ;Routine to print error message at DPTR. prterr: jmp wrstr ;Routine to handle input parameter error. badprm: mov DPTR,#bpmsg jmp wrstr bpmsg: db 'Bad Parameter',0 ;*********************************************************** ;**** LCD Display Routines **** ;****************************** ;LCD Registers addresses LCD_CMD_WR equ 00h LCD_DATA_WR equ 01h LCD_BUSY_RD equ 02h LCD_DATA_RD equ 03h LCD_PAGE equ 80h ;LCD Commands LCD_CLS equ 1 LCD_HOME equ 2 LCD_SETMODE equ 4 LCD_SETVISIBLE equ 8 LCD_SHIFT equ 16 LCD_SETFUNCTION equ 32 LCD_SETCGADDR equ 64 LCD_SETDDADDR equ 128

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值