题目描述:
请使用MFC框架或者Windows API实现一个简单的计算器,主要实现以下功能:
(1)程序必须有操作UI,不能是控制台程序。
(2)计算功能包括:加、减、乘、除、求模、求余、位移运算
所有计算因子必须是可输入的,不能内置在代码里面。
1、DLL使用C++实现表达式求值,后缀表达式求值,利用两个栈来模拟实现表达式求值
此处设计DLL的类导出
/* 堆栈类,用于表达式求值 */ #include<iostream> #include<string> //#include<string.h> #include<stdlib.h> using namespace std; #ifndef STACK_SIZE #define STACK_SIZE 100 #endif #ifndef LIB_H #define LIB_H #ifdef DLL_FILE class _declspec(dllexport) myStack //导出类 #else class _declspec(dllimport) myStack //导入类 #endif { private: float value[STACK_SIZE];//存放数值 int pop_v; char sign[STACK_SIZE];//存放运算符 int pop_s; float result;//存放表达式最终的值 public: myStack() { pop_v = -1; result = 0; pop_s = -1; memset(value,0,sizeof(value)); memset(sign,'\0',sizeof(sign)); } bool push(float val);//压栈 bool push(char ch); float pop_value();//出栈 char pop_sign(); float getPop_v();//获取栈顶元素 char getPop_s(); void divideExp(char* expression);//拆分表达式 float Calculate(); ~myStack(); }; #endif
#ifndef DLL_FILE #define DLL_FILE #endif #include"lib.h" bool myStack::push(float val) { if(pop_v < STACK_SIZE) { pop_v++;//栈顶指针加1 value[pop_v] = val; return true; } return false; } bool myStack::push(char ch) { if(pop_s < STACK_SIZE) { pop_s++;//栈顶指针加1 sign[pop_s] = ch; return true; } return false; } float myStack::pop_value() { float rt; if(pop_v != -1 && pop_v < STACK_SIZE) { rt = value[pop_v]; pop_v--;//栈顶指针减1 return rt; } return -1; } char myStack::pop_sign() { char ch = 'N'; if(pop_s != -1 && pop_s < STACK_SIZE) { ch = sign[pop_s]; pop_s--;//栈顶指针减1 } return ch; } float myStack::getPop_v() { return value[pop_v]; } char myStack::getPop_s() { return sign[pop_s]; } float myStack::Calculate() { return result; } void myStack::divideExp(char* expression) { int len = strlen(expression); char tmp[20]; float val = 0.0;//接收表达式截取的数值 float val1 = 0.0;//接收弹栈数值 int p = 0;//字符串指针 int start = 0;//子串起始位置 push('#');//#优先级最低,初始化运算符栈 char sig; while(p < len) { memset(tmp,'\0',sizeof(tmp)); /*截取数字字符串*/ while(expression[p] >= '0' && expression[p] <= '9' || expression[p] == '.') { p++; } strncpy(tmp,&expression[start],p-start); //val = atoi(tmp);//char* to int sscanf(tmp,"%f",&val); if(expression[p] == '\0')// 表达式已经拆分完,此时如果两个栈中还有值,一步一步弹栈计算表达式的值 { while((val1 = pop_value()) != -1)//后缀表达式求值 { sig = pop_sign(); if(sig == '+') val += val1; else if(sig == '-') val = val1 - val; else if(sig == '*') val *= val1; else if(sig == '/') val = val1/val; else break; } result = val; } sig = getPop_s();//获取运算符与当前栈顶运算符优先级比较 switch(sig) { case '#': push(val); push(expression[p]);//运算符压栈 break; case '+'://运算符栈顶元素为"+",优先级( '+' > '+'、'-'),('+'<'*'、'/') switch(expression[p]) { case '+': case '-': val1 = pop_value(); pop_sign(); push(val1+val); push(expression[p]);//运算符压栈 break; case '*': case '/': push(val); push(expression[p]);//运算符压栈 break; } break; case '-'://运算符栈顶元素为"-" switch(expression[p]) { case '+': case '-': val1 = pop_value(); pop_sign(); push(val1-val); push(expression[p]);//运算符压栈 break; case '*': case '/': push(val); push(expression[p]);//运算符压栈 break; } break; case '*'://运算符栈顶元素为"*",优先级‘*’>‘+’、‘-’、‘/’ val1 = pop_value(); pop_sign(); push(val1*val); push(expression[p]);//运算符压栈 break; case '/'://运算符栈顶元素为"/",优先级‘/’>‘+’、‘-’、‘*‘ val1 = pop_value(); pop_sign(); push(val1/val); push(expression[p]);//运算符压栈 break; } p++; start = p; } } myStack::~myStack() { }2、新建MFC exe工程
需要导入DLL定义的类,首先包含头文件lib.h
#include "....\lib.h"
之后就可直接使用该类定义对象了。
界面布局:
功能实现:
char expression[1024];//全局变量用于存储表达式 //memset(expression,' ',sizeof(expression)); float result = 0.0; void CWork3Dlg::UpDateData()//更新显示区的值 { GetDlgItem(IDC_EDIT1) -> SetWindowText(expression); } void CWork3Dlg::OnButton1() //1 { // TODO: Add your control notification handler code here strcat(expression,"1"); UpDateData(); } void CWork3Dlg::OnButton2() //2 { // TODO: Add your control notification handler code here strcat(expression,"2"); UpDateData(); } void CWork3Dlg::OnButton3() //3 { // TODO: Add your control notification handler code here strcat(expression,"3"); UpDateData(); } void CWork3Dlg::OnButton4() //* { // TODO: Add your control notification handler code here int len = strlen(expression); if(len != 0 && expression[len-1] != '*') { strcat(expression,"*"); UpDateData(); } } void CWork3Dlg::OnButton5() //4 { // TODO: Add your control notification handler code here strcat(expression,"4"); UpDateData(); } void CWork3Dlg::OnButton6() //5 { // TODO: Add your control notification handler code here strcat(expression,"5"); UpDateData(); } void CWork3Dlg::OnButton7() //6 { // TODO: Add your control notification handler code here strcat(expression,"6"); UpDateData(); } void CWork3Dlg::OnButton8() // / { // TODO: Add your control notification handler code here int len = strlen(expression); if(len != 0 && expression[len-1] != '/') { strcat(expression,"/"); UpDateData(); } } void CWork3Dlg::OnButton9() //7 { // TODO: Add your control notification handler code here strcat(expression,"7"); UpDateData(); } void CWork3Dlg::OnButton10() //8 { // TODO: Add your control notification handler code here strcat(expression,"8"); UpDateData(); } void CWork3Dlg::OnButton11() //9 { // TODO: Add your control notification handler code here strcat(expression,"9"); UpDateData(); } void CWork3Dlg::OnButton12() //+ { // TODO: Add your control notification handler code here int len = strlen(expression); if(len != 0 && expression[len-1] != '+') { strcat(expression,"+"); UpDateData(); } } void CWork3Dlg::OnButton13() //0 { // TODO: Add your control notification handler code here strcat(expression,"0"); UpDateData(); } void CWork3Dlg::OnButton19() //后退 { // TODO: Add your control notification handler code here int len = strlen(expression); expression[len-1] = '\0'; UpDateData(); } void CWork3Dlg::OnButton14() //输入小数点 { // TODO: Add your control notification handler code here int len = strlen(expression); if(len == 0) return; int p = len-1; while(p > 0)//是数字 { if(expression[p] >= '0' && expression[p] <= '9')//排除一个数值中间有多个小数点的情况 p--; else break; } if(expression[p] == '.') return; if(len != 0 && expression[len-1] != '.') { strcat(expression,"."); UpDateData(); } } void CWork3Dlg::OnButton15() //- { // TODO: Add your control notification handler code here int len = strlen(expression); if(len != 0 && expression[len-1] != '-') { strcat(expression,"-"); UpDateData(); } } void CWork3Dlg::OnButton16() //后退 { // TODO: Add your control notification handler code here int len = strlen(expression); expression[len-1] = '\0'; UpDateData(); } void CWork3Dlg::OnButton18() { // TODO: Add your control notification handler code here } #pragma comment(lib,"workdll.lib");//静态加载 void CWork3Dlg::OnButton17() { // TODO: Add your control notification handler code here myStack mystack; mystack.divideExp(expression); result = mystack.Calculate(); memset(expression,'\0',sizeof(expression)); // itoa(result,expression,10);//int to char //float型转换为char* CString str; str.Format("%f",result); char* ch = (LPSTR)(LPCTSTR)str; strcpy(expression,ch); UpDateData(); } void CWork3Dlg::OnButton20()//清屏 { // TODO: Add your control notification handler code here memset(expression,'\0',sizeof(expression)); result = 0; UpDateData(); }