一个简易的计算器

支持的运算符有+、-、*、/、^、sin()、cos()、log()、ln()。

支持的操作数为正数(暂未实现负数和小数)。

以前在王道论坛上做过实现+、-、*、/的运算,现在多了几个三角函数运算。

尝试着做了一下,暂看不出哪里有错误,哪位大神看出来了请指点一下哈!

▶▶▶小知识点:在vs2005以及之后的版本中,推荐用scanf_s、printf_s、gets_s代替scanf、printf、gets。

▶▶▶理由:scanf()等在读取时不检查边界,所以可能会造成内存泄露。所以vc++2005/2008中提供了scanf_s()等函数,在最新的VS2013中也提供了scanf_s()。在调用时,必须提供一个数字以表明最多读取多少位字符。

#include <cstdio>
#include <stack>
#include <math.h>

using namespace std;
//   +			1
//   -			2
//   *			3
//   /			4
//   ^			5
//   sin()		6
//   cos()		7
//   log()		8
//   ln()		9
//	 (			10
//   )			11

char str[220];
//mat[i][j]==1表示i的优先级比j的优先级大
int mat[12][12]={
	1,0,0,0,0,0,0,0,0,0,1,0,
	1,0,0,0,0,0,0,0,0,0,1,0,
	1,0,0,0,0,0,0,0,0,0,1,0,
	1,1,1,0,0,0,0,0,0,0,1,0,
	1,1,1,0,0,0,0,0,0,0,1,0,
	1,1,1,1,1,0,0,0,0,0,1,0,
	1,1,1,1,1,0,0,0,0,0,1,0,
	1,1,1,1,1,0,0,0,0,0,1,0,
	1,1,1,1,1,0,0,0,0,0,1,0,
	1,1,1,1,1,0,0,0,0,0,1,0,
	1,1,1,1,1,1,1,1,1,1,1,1,
	1,0,0,0,0,0,0,0,0,0,1,0,
};

stack<double> in;	//数字栈
stack<int> op;		//运算符

void getOp(bool &reto,int &retn,int &i){
	if(i==0&&op.empty()){
		reto=true;
		retn=0;
		return;
	}
	if(str[i]==0){
		reto=true;
		retn=0;
		return;
	}
	if(str[i]<='9'&&str[i]>='0'){
		reto=false;
	}
	else{
		reto=true;
		switch(str[i]){
			case '+':
				retn=1;
				i+=1;
				break;
			case '-':
				retn=2;
				i+=1;
				break;
			case '*':
				retn=3;
				i+=1;
				break;
			case '/':
				retn=4;
				i+=1;
				break;
			case '^':
				retn=5;
				i+=1;
				break;
			case 's':
				retn=6;
				i+=3;
				break;
			case 'c':
				retn=7;
				i+=3;
				break;
			case 'l':
				if(str[i+1]=='o'){
					retn=8;
					i+=3;
				}
				else {
					retn=9;
					i+=2;
				}
				break;
			case '(':
				retn=10;
				i+=1;
				break;
			case ')':
				retn=11;
				i+=1;
				break;
			default:
				break;
		}
		return;
	}
	retn=0;
	for(;str[i]<='9'&&str[i]>='0';i++){
		retn*=10;
		retn+=str[i]-'0';
	}
	return ;
}

int main(){
	printf_s("本程序为简易计算。\n.支持的运算符有:+、-、*、/、^、sin()、cos()、log()、ln()。\n");
	printf_s("支持的操作数为整数;公式中不含有空格;\n");
	while(gets_s(str)){
		if(str[0]=='0'&&str[1]=='0')break;
		bool retop; int retnum;
		int idx=0;
		while(!op.empty())op.pop();
		while(!in.empty())in.pop();
		while(true){
			getOp(retop,retnum,idx);
			if(retop==false){
				in.push((double)retnum);
			}
			else{
				double a,b;
				if(op.empty()==true||(retnum!=11&&mat[retnum][op.top()]==1)){
					op.push(retnum);
				}
				else{
					while(mat[retnum][op.top()]==0){
						int ret=op.top();
						op.pop();
						if(ret<=5||ret==8){
							b=in.top();in.pop();
							a=in.top();in.pop();
							if(ret==1)
								a=a+b;
							else if(ret==2)
								a=a-b;
							else if(ret==3)a=a*b;
							else if(ret==4)a=a/b;
							else if(ret==5)a=pow(a,b);
							else if(ret==8)a=log(b)/log(a);
						}
						else{
							a=in.top();in.pop();
							if(ret==6)a=sin(a);
							else if(ret==7)a=cos(a);
							else if(ret==9)a=log(a);
						}
						in.push(a);
					}
					if(retnum!=11)op.push(retnum);
					else op.pop();

				}
			}
			if(op.size()==2&&op.top()==0)break;
		}
		printf_s("%.3f\n",in.top());
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值