用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. //UsingC++style
  4. template<typenameCustomType>//可将任意类型应用于此
  5. structCustomStruct
  6. {
  7. CustomStruct():elem(0),link(0){}//默认构造函数
  8. CustomTypeelem;
  9. CustomStruct*link;
  10. };
  11. template<typenameCustomType>
  12. classJStack
  13. {
  14. public:
  15. JStack():base(0),top(0),JStackSize(0){}//默认构造函数
  16. ~JStack(){}//默认析构函数
  17. boolInitJStack(void);//初始化栈
  18. CustomTypeGetTop(void);//取出栈顶的元素
  19. boolPop(void);//将元素从栈中弹出
  20. boolPush(CustomTypee);//将元素压入栈顶
  21. private:
  22. CustomStruct<CustomType>*base;//栈底
  23. CustomStruct<CustomType>*top;//栈顶
  24. intJStackSize;//栈的元素个数
  25. };//栈结构的定义
  26. //boolIsOperator(charc);
  27. charCharProcess(JStack<float>&opndStack);
  28. charPrecede(chartheta1,chartheta2);
  29. floatEvaluateExpression(void);
  30. floatGetAnswer(floata,charc,floatb);
  31. #endif

define.cpp代码:

Code:
  1. #include<iostream>
  2. #include<string.h>
  3. #include"define.h"
  4. usingnamespacestd;
  5. template<typenameCustomType>
  6. boolJStack<CustomType>::InitJStack(void)//初始化栈
  7. {
  8. base=top=newCustomStruct<CustomType>;
  9. if(!base)
  10. returnfalse;
  11. returntrue;
  12. }
  13. template<typenameCustomType>
  14. boolJStack<CustomType>::Push(CustomTypee)//将元素压入栈顶
  15. {
  16. CustomStruct<CustomType>*temp;
  17. temp=top;
  18. top=newCustomStruct<CustomType>;
  19. if(!top)
  20. returnfalse;
  21. top->elem=e;
  22. top->link=temp;
  23. returntrue;
  24. }//此方法相当于头插法
  25. template<typenameCustomType>
  26. boolJStack<CustomType>::Pop(void)//将元素从栈中弹出
  27. {
  28. CustomStruct<CustomType>temp;
  29. temp.elem=top->elem;
  30. temp.link=top->link;
  31. deletetop;
  32. top=temp.link;
  33. returntrue;
  34. }
  35. template<typenameCustomType>
  36. CustomTypeJStack<CustomType>::GetTop(void)//取出栈顶的元素
  37. {
  38. returntop->elem;
  39. }
  40. floatEvaluateExpression(void)
  41. {//计算表达式的函数
  42. charc=0,operand;
  43. floata=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. returnopndStack.GetTop();
  82. }
  83. charCharProcess(JStack<float>&opndStack)
  84. {
  85. chartemp[16]={0};//定义临时变量,用来存储字符串化的数字
  86. charc;//定义一个字符
  87. inti=0;//定义一个自增的变量
  88. cin.get(c);//读取一个字符
  89. if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
  90. returnc;
  91. while(c>='0'&&c<='9'||c=='.')
  92. {//若是数字的话,将其放在临时的变量中
  93. temp[i++]=c;
  94. cin.get(c);//再取一个字符
  95. }//剩下的就是操作符了
  96. opndStack.Push(atof(temp));
  97. returnc;//返回当前操作符
  98. }
  99. charPrecede(chartheta1,chartheta2)
  100. {//对运算符的优先级进行判断的函数
  101. if(theta1=='+'||theta1=='-')
  102. {
  103. if(theta2=='+'||theta2=='-'||theta2==')'||theta2=='=')
  104. return'>';
  105. elsereturn'<';
  106. }
  107. if(theta1=='*'||theta1=='/')
  108. {
  109. if(theta2=='(')
  110. return'<';
  111. elsereturn'>';
  112. }
  113. if(theta1=='(')
  114. {
  115. if(theta2==')')
  116. return'=';
  117. elseif(theta2=='=')
  118. return'';
  119. elsereturn'<';
  120. }
  121. if(theta1==')')
  122. {
  123. if(theta2=='(')
  124. return'';
  125. elsereturn'>';
  126. }
  127. if(theta1=='=')
  128. {
  129. if(theta2=='=')
  130. return'=';
  131. elseif(theta2==')')
  132. return'';
  133. elsereturn'<';
  134. }
  135. return0;//返回错误信息
  136. }
  137. floatGetAnswer(floata,charoperand,floatb)
  138. {
  139. switch(operand)
  140. {
  141. case'+':returna+b;
  142. case'-':returna-b;
  143. case'*':returna*b;
  144. case'/':returna/b;
  145. }
  146. return0.0f;
  147. }

mainframe.cpp代码:

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值