MFC之静态调用DLL实现简易计算器

题目描述:

请使用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"

之后就可直接使用该类定义对象了。

界面布局:

MFC之静态调用DLL实现简易计算器_第1张图片

功能实现:

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();
}

当然没有实现求模求余和以为运算,表达式求值也没有加括号,有机会再加上吧~~~


你可能感兴趣的:(mfc,dll,计算器)