用vs2005编写控制台程序,用来进行四则运算

这是我的实验报告,原封不动地弄上来了,本来是给老师看的呢。

项目名称:实现四则运算:
项目实施方法:建立一个栈,并建立两个对象,用来对操作符和操作数进行操作。从左至右对输入的文本进行扫描,将相应的操作符和操作数进行压入,然后进行相应的运算。
我使用了memcpy函数,起初担心memcpy函数的效率问题,但是网络上是这样回答的。
“最近又听到有人在讲memcpy的效率问题,实在是忍不住了,基本上很多人对memcpy的原理都是一知半解,大部分认为memcpy是一个char到char的拷贝的循环,担心它的效率。
实际上,memcpy是一个效率最高的内存拷贝函数,他不会那么傻,来做一个一个字节的内存拷贝,在地址不对齐的情况下,他是一个字节一个字节的拷,地址对齐以后,就会使用CPU字长来拷(和dma类似),32bit或64bit,还会根据cpu的类型来选择一些优化的指令来进行拷贝。
总的来说,memcpy的实现是和CPU类型、操作系统、cLib相关的。毫无疑问,它是内存拷贝里效率最高的,请放心使用。”
因此在程序设计之初曾经想过两种方案:
副本一、使用memcpy函数,可以采用动态开辟数组来模拟顺序栈的实现;
副本二、不使用memcpy函数,对链表的操作会显得慢些。
最终选择了没有使用memcpy()函数。
压入栈的伪代码:
1 将top节点备份给temp;
2 开辟一个节点,赋给top指针;
3 将temp指针的值赋给top的成员link。

弹出栈的伪代码:
1 取出元素;
2 删除节点;
3 将top指针指向下一个节点;
4 返回元素。

处理当前字符的函数(CharProcess()函数)的伪代码:
1 若是字符,则直接返回;
2 若是数字,则取下一个字符,并循环判断
3 在判断中若是字符,则对数字进行压栈操作,并返回。

计算表达式的函数(EnvaluateExpression()函数)的伪代码:
1 定义对象,并初始化;
2 对存储操作符的栈压入“=”字符;
3 在字符不为“=”或者“)”,则运行CharProcess()函数;
4 若有括号匹配现象,消去括号;
5 运行Precede()函数,并对其产生不同的返回值进行不同的操作;
6 若未产生“=”匹配现象,则循环3~6步操作;
7 返回栈顶元素。

注意:
1 此程序仅表示了核心的代码,若用户误输入了错误的数据,则会产生各种的错误;
2 此程序仅支持“+-*/()”四则运算,尚不满足科学计算要求。

程序特点:链式栈、支持四则运算、支持一次性输入两位数及以上、支持浮点型数
 

程序代码:define.h代码:

Code:
  1. #ifndef _J_DEFINE_H_   
  2. #define _J_DEFINE_H_   
  3. //Using C++ style   
  4. template<typename CustomType>//可将任意类型应用于此   
  5. struct CustomStruct   
  6. {   
  7.     CustomStruct():elem(0),link(0){}//默认构造函数   
  8.     CustomType elem;   
  9.     CustomStruct* link;   
  10. };   
  11. template<typename CustomType>   
  12. class JStack   
  13. {   
  14. public:   
  15.     JStack():base(0),top(0),JStackSize(0){}//默认构造函数   
  16.     ~JStack(){}//默认析构函数   
  17.     bool InitJStack( void );//初始化栈   
  18.     CustomType GetTop( void );//取出栈顶的元素   
  19.     bool Pop( void );//将元素从栈中弹出   
  20.     bool Push(CustomType e);//将元素压入栈顶   
  21. private:   
  22.     CustomStruct<CustomType>* base;//栈底   
  23.     CustomStruct<CustomType>* top;//栈顶   
  24.     int JStackSize;//栈的元素个数   
  25. };//栈结构的定义   
  26. //bool IsOperator(char c);   
  27. char CharProcess( JStack<float>& opndStack );   
  28. char Precede(char theta1, char theta2);   
  29. float EvaluateExpression( void );   
  30. float GetAnswer(float a,char c,float b);   
  31. #endif   

define.cpp代码:

Code:
  1. #include<iostream>   
  2. #include<string.h>   
  3. #include "define.h"   
  4. using namespace std;   
  5. template<typename CustomType>   
  6. bool JStack<CustomType>::InitJStack( void )//初始化栈   
  7. {   
  8.     base = top = new CustomStruct<CustomType>;   
  9.     if ( !base )   
  10.         return false;   
  11.     return true;   
  12. }   
  13. template<typename CustomType>   
  14. bool JStack<CustomType>::Push(CustomType e)//将元素压入栈顶   
  15. {   
  16.     CustomStruct<CustomType>* temp;   
  17.     temp = top;   
  18.     top = new CustomStruct<CustomType>;   
  19.     if ( !top )   
  20.         return false;   
  21.     top->elem = e;   
  22.     top->link = temp;   
  23.     return true;   
  24. }//此方法相当于头插法   
  25. template<typename CustomType>   
  26. bool JStack<CustomType>::Pop( void )//将元素从栈中弹出   
  27. {   
  28.     CustomStruct<CustomType> temp;   
  29.     temp.elem = top->elem;   
  30.     temp.link = top->link;   
  31.     delete top;   
  32.     top = temp.link;   
  33.     return true;   
  34. }   
  35. template<typename CustomType>   
  36. CustomType JStack<CustomType>::GetTop( void )//取出栈顶的元素   
  37. {   
  38.     return top->elem;   
  39. }   
  40. float EvaluateExpression( void )   
  41. {   //计算表达式的函数   
  42.     char c=0,operand;   
  43.     float a=0,b=0;//定义计算的操作数   
  44.     JStack<float> opndStack;//存储操作数的栈   
  45.     JStack<char> operStack;//存储操作符的栈   
  46.     opndStack.InitJStack();//初始化   
  47.     operStack.InitJStack();//初始化   
  48.     operStack.Push('=');   
  49.     do  
  50.     {   
  51.         if ( c != '=' && c != ')')//如果当前未到等号位置,则继续处理字符   
  52.             c = CharProcess( opndStack );   
  53.         if ( operStack.GetTop() == '(' && c == ')')   
  54.         {   //消去括号   
  55.             operStack.Pop();   
  56.             cin.get( c );   
  57.         }   
  58.         switch( Precede(operStack.GetTop(), c) )   
  59.         {   //对不同的情况进行操作   
  60.         case '<'://低优先级   
  61.             operStack.Push( c );break;   
  62.         case '='://优先级相等   
  63.             operStack.Pop();   
  64.             break;   
  65.         case '>'://高优先级   
  66.             b = opndStack.GetTop();//右操作数   
  67.             opndStack.Pop();//右操作数弹出   
  68.             operand = operStack.GetTop();//操作符   
  69.             operStack.Pop();//操作符弹出   
  70.             a = opndStack.GetTop();//左操作数   
  71.             opndStack.Pop();//左操作数弹出   
  72.             opndStack.Push( GetAnswer( a, operand, b) );   
  73.             if ( c != '=' && c != ')')//如果不是等号或者右边括号   
  74.                  operStack.Push( c );//要将当前操作符入栈   
  75.             break;   
  76.         case ' ':   
  77.             break;   
  78.         }   
  79.     }   
  80.     while ( c != '=' || operStack.GetTop() != '=');//若未到等于符号,继续读取   
  81.     return opndStack.GetTop();   
  82. }   
  83. char CharProcess( JStack<float>& opndStack )   
  84. {   
  85.     char temp[16] ={ 0 };//定义临时变量,用来存储字符串化的数字   
  86.     char c;//定义一个字符   
  87.     int i = 0;//定义一个自增的变量   
  88.     cin.get( c );//读取一个字符   
  89.     if ( c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')' )   
  90.         return c;   
  91.     while ( c>= '0' && c <= '9' || c == '.')   
  92.     {   //若是数字的话,将其放在临时的变量中   
  93.         temp[i++] = c;   
  94.         cin.get( c );//再取一个字符   
  95.     }   //剩下的就是操作符了   
  96.     opndStack.Push( atof(temp) );   
  97.     return c;//返回当前操作符   
  98. }   
  99.   
  100. char Precede(char theta1, char theta2)   
  101. {   //对运算符的优先级进行判断的函数   
  102.     if (theta1 == '+'||theta1 =='-')   
  103.     {   
  104.         if ( theta2 == '+'||theta2 == '-'|| theta2 ==')'||theta2 == '=')   
  105.             return '>';   
  106.         else return '<';   
  107.     }   
  108.     if (theta1 == '*'||theta1 =='/')   
  109.     {   
  110.         if ( theta2 == '(' )   
  111.             return '<';   
  112.         else return '>';   
  113.     }   
  114.     if (theta1 == '(')   
  115.     {   
  116.         if ( theta2 == ')' )   
  117.             return '=';   
  118.         else if ( theta2 == '=')   
  119.             return ' ';   
  120.         else return '<';   
  121.     }   
  122.     if (theta1 == ')')   
  123.     {   
  124.         if (theta2 == '(')   
  125.             return ' ';   
  126.         else return '>';   
  127.     }   
  128.     if (theta1 == '=')   
  129.     {   
  130.         if (theta2 == '=')   
  131.             return '=';   
  132.         else if (theta2 == ')')   
  133.             return ' ';   
  134.         else return '<';   
  135.     }   
  136.     return 0;//返回错误信息   
  137. }   
  138. float GetAnswer(float a,char operand,float b)   
  139. {   
  140.     switch ( operand )   
  141.     {   
  142.     case '+':return a+b;   
  143.     case '-':return a-b;   
  144.     case '*':return a*b;   
  145.     case '/':return a/b;   
  146.     }   
  147.     return 0.0f;   
  148. }   

mainframe.cpp代码:

Code:
  1. #include <iostream>   
  2. #include "define.h"   
  3. int main(int arg, char** argv)   
  4. {   
  5.     float answer;   
  6.     answer =  EvaluateExpression();   
  7.     std::cout<<"上述式子的结果是:"<<answer<<'/n';   
  8.     return 0;   
  9. }  

程序的运行结果如图所示:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值