简易计算器项目(C/C++版)

大一暑假实训项目总结(简易计算器C++版)

因为疫情原因,我们这一届的实训就被放在了暑假的尾声进行,也就是线上进行。也是因为快开学了,便于开学后进行项目交流和答辩。
我们组还是和大一上学期一样,那五个老同志。只不过项目不一样了,上次是学生成绩管理系统,而这次是简易计算器的实现。
我们这次的实训项目也确实比上次难一点,因为我们是从网上找到代码,但是又跟它有点不同,我们在它的基础上增加了一个比较的功能,所以我们组大部分时间都在想如何将它实现,确实挺头疼的。
我们这个计算器项目,顾名思义就是实现计算器的相关功能,是用C++语言实现的。当然他跟C语言也没有很大的区别,只要将头文件和输入输出方式更换一下就可以换成C语言版本的。它的功能主要包括加、减、乘、除、乘方、立方、开根号、计算sinx、cosx、tanx等等,还有一个就是我们组一直想实现的功能就是比较功能。
先展示一下运行的图片:
1 简陋的登陆界面
在这里插入图片描述
2 功能界面
在这里插入图片描述
3 计算功能示例图片
在这里插入图片描述
4 判断功能示例图片
在这里插入图片描述
5 退出界面
在这里插入图片描述
最后上代码,这是的这段时间的成果啊,说多了都是泪,代码中也有注释,可以帮助阅读。

#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;

const double pi = 3.14159265;        //&&pi = acos(-1)
const double e = 2.718281828459;
const int SIZE = 1000;

typedef struct node//为了处理符号而建立的链表(如: 1+(-2))
{
	char data;
	node *next;
}node;

typedef struct stack_num//存储 数 的栈
{
	double *top;
	double *base;
}stack_num;

typedef struct stack_char//存储 运算符号 的栈
{
	char *top;
	char *base;
}stack_char;

stack_num S_num;//定义
stack_char S_char;//定义
char fu[18] = {'\n', ')', '+', '-', '*', '/', '%', '^',
'Q', 'L', 'C', 'S', 'T', 'c', 's', 't', '('};
int compare[1000];//表现出各运算符号的优先级
double shu[1000];//存储 "数" 的数组
double dai_result;//运算的结果,是为了处理 M 运算(简介函数里有M的定义)
int biao = 0;//和dia_result 一样,为了处理 M 运算
string line;//输入的所要计算的表达式      //&&char line[SIZE];//输入的所要计算的表达式
int judge;//用于判断是算术表达式还是关系表达式
int cnt;

//初始化
void init()
{
	compare[fu[0]] = -2;//用数字的大小表现出符号的优先级
	compare[fu[1]] = -1;
	compare[fu[2]] = 2;
	compare[fu[3]] = 2;
	compare[fu[4]] = 4;
	compare[fu[5]] = 4;
	compare[fu[6]] = 4;
	compare[fu[7]] = 5;
	for(int i = 8; i <= 15; i++)
		compare[fu[i]] = 6;
	compare[fu[16]] = 7;

	S_num.base = (double*)malloc(sizeof(double)*SIZE);//为栈开辟空间
	S_char.base = (char*)malloc(sizeof(char)*SIZE);//同上
	S_num.top = S_num.base;
	S_char.top = S_char.base;
}

//数字进栈
void push_num(double n)
{
	* ++S_num.top = n;
}

//运算符号进栈
void push_char(char c)
{
	* ++S_char.top = c;
}

//数字出栈
double pop_num()
{
	double m = *S_num.top;
	S_num.top--;
	return m;
}

//运算符号出栈
char pop_char()
{
	char cc = *S_char.top;
	S_char.top--;
	return cc;
}

//得到运算符号的栈中最顶端的运算符号
char get_top_char()
{
	return *S_char.top;
}

//对两个数计算(含是双目运算符:如 *, / 等等)
double operate(double y, char c, double x)
{
	double r;
	if(c == '-')
		r = x - y;
	else if(c == '+')
		r = x + y;
	else if(c == '/' && y != 0)
		r = x / y;
	else if(c == '*')
		r = x * y;
	else if(c == '^')
	{
		r = 1;
		for(int i = 1; i <= y; i++)
			r *= x;
	}
	else if(c == '%')
	{
		int r0 = (int)x % (int)y;
		r = double(r0);
	}
	return r;
}
//对一个数运算(含单目运算符:如log(L), sin(S) 等等)
double operate_one(double one, char cc)
{
	double r;
	if(cc == 'Q')
		r = sqrt(one);
	else if(cc == 'C')
		r = cos(one);
	else if(cc == 'S')
		r = sin(one);
	else if(cc == 'T')
		r = tan(one);
	else if(cc == 'c')
		r = acos(one);
	else if(cc == 's')
		r = asin(one);
	else if(cc == 't')
		r = atan(one);

	return r;
}

//求对数的值
double operate_L(double a, double b, char dian)
{
	double r = log(b) / log(a);
	return r;
}

//对整个表达式的计算
double compute()
{
	char c;//表示运算符号
	int p = 0;//用于shu[++p], 先初始化
	int i, j;

	init();//进行初始化

	push_char('\n');
	line[line.size()] = '\n';
	line[line.size()+1] = '\0';
	if(biao)
		push_num(dai_result);//把运算的结果先进栈, 在这个结果的基础上继续进行运算
	biao = 0;
	for(i = 0; line[i] != '\0';)//把表达式中的数字字符串转化成可计算的数字
	{
		int flag = 0;
		int flag1 = 1;//标记是否是运算符号
	//	int flag2 = 1;//标记是否出现'_';
		double h = 0;
		int ge;//位数
		int biao_dian = 0;//是否是小数的类型

		while(1)
		{
			flag1 = 1;
			for(j = 0; j <= 16; j++)
			{
				if(line[i] == fu[j])
				{
					flag1 = 0;
					break;
				}
			}
			if(line[i] == '_')
			{
				break;
			}
			if(line[i] == '.')
			{
				i++;
				ge = 0;
				biao_dian = 1;
			}
			if(line[i] == 'P')
			{
				shu[++p] = pi;
				i++;
				break;
			}
			if(line[i] == 'E')
			{
				shu[++p] = e;
				i++;
				break;
			}
			if(flag1)
			{
				h = h * 10 + (line[i] - '0');
				flag = 1;
				i++;
				if(biao_dian)
					ge++;
			}
			else
				break;
		}
		if(flag)
		{
			if(biao_dian)
			{
				int r = 1;
				for(int k = 1; k <= ge; k++)
					r *= 10;
				h /= r;
			}
			shu[++p] = h;//把转化而来的数字存于数组
		}
		if(line[i] == '+')
			shu[++p] = -1;
		else if(line[i] == '-')
			shu[++p] = -2;
		else if(line[i] == '*')
			shu[++p] = -3;
		else if(line[i] == '/')
			shu[++p] = -4;
		else if(line[i] == '%')
			shu[++p] = -5;
		else if(line[i] == '^')
			shu[++p] = -6;
		else if(line[i] == 'Q')
			shu[++p] = -7;
		else if(line[i] == 'L')
			shu[++p] = -8;
		else if(line[i] == 'C')
			shu[++p] = -9;
		else if(line[i] == 'S')
			shu[++p] = -10;
		else if(line[i] == 'T')
			shu[++p] = -11;
		else if(line[i] == 'c')
			shu[++p] = -12;
		else if(line[i] == 's')
			shu[++p] = -13;
		else if(line[i] == 't')
			shu[++p] = -14;
		else if(line[i] == '(')
			shu[++p] = -15;
		else if(line[i] == ')')
			shu[++p] = -16;
		else if(line[i] == '\n')
			shu[++p] = -17;
		i++;
	}
	i = 1;
	while(shu[i] != -17 || get_top_char() != '\n')
	{
		double m = shu[i];

		if(m >= 0)
		{
			push_num(m);
			i++;
		}
		else
		{
			if(m == -1)
				c = '+';
			else if(m == -2)
				c = '-';
			else if(m == -3)
				c = '*';
			else if(m == -4)
				c = '/';
			else if(m == -5)
				c = '%';
			else if(m == -6)
				c = '^';
			else if(m == -7)
				c = 'Q';
			else if(m == -8)
				c = 'L';
			else if(m == -9)
				c = 'C';
			else if(m == -10)
				c = 'S';
			else if(m == -11)
				c = 'T';
			else if(m == -12)
				c = 'c';
			else if(m == -13)
				c = 's';
			else if(m == -14)
				c = 't';
			else if(m == -15)
				c = '(';
			else if(m == -16)
				c = ')';
			else if(m == -17)
				c = '\n';
			char ch = get_top_char();//得到最顶端运算符号
			if(compare[ch] < compare[c])//运算符号级别的比较
			{
				push_char(c);
				i++;
			}
			else if(ch == '(' && c == ')')
			{
				pop_char();
				i++;
			}
			else if(compare[ch] >= compare[c] && ch != '(' && ch != '\n')
			{
				if(ch == 'Q' || ch == 'C' || ch == 'S'|| ch == 'T'
					|| ch == 'c' || ch == 's' || ch == 't')
				{
					double one = pop_num();
					char dian = pop_char();
					push_num(operate_one(one, dian));
				}
				else if(ch == 'L')
				{
					double one_L = pop_num();
					double two_L = pop_num();
					char dian = pop_char();
					push_num(operate_L(two_L, one_L, dian));
				}
				else
				{
					double x = pop_num();
					double y = pop_num();
					char dian = pop_char();
					if(dian == '/' && x == 0)//判断是否除了"零"
					{
						cout<<"由于您除了零,结果将是错误的"<<endl;
					}
					push_num(operate(x, dian, y));//把进行一次计算的结果入栈
				}
			}
			else
			{
				push_char(c);
				i++;
			}
		}
	}
	double result = pop_num();//得到结果

	return result;
}

//检查表达式括号是否匹配
int check_kuohao()
{
	int i, f = 0;
	int kuo[SIZE], key = 1;

	memset(kuo, 0, sizeof(kuo));
	for(i = 0; line[i] != '\0'; i++)
	{
		if(line[i] == '(')
			kuo[++f] = 1;
		else if(line[i] == ')')
		{
			if(kuo[f] == 1)
			{
				kuo[f] = 0;
				f--;
			}
			else
			{
				key = 0;
				break;
			}
		}
	}
	if(key && f == 0)
		return 1;
	else
		return 0;
}

//检查运算符号是否合法(如: 1 +* 4)
int check_char()
{
	int i, ge;
	for(i = 0; line[i] != '\0'; )
	{
		ge = 0;
		while(line[i] == '+' || line[i] == '-' || line[i] == '*'
			|| line[i] == '/' || line[i] == '%' || line[i] == '^'
			|| line[i] == 'Q' || line[i] == 'L' || line[i] == 'S'
			|| line[i] == 'C' || line[i] == 'T' || line[i] == 's'
			|| line[i] == 'c' || line[i] == 't')
		{
			ge++;
			i++;
		}
		i++;
	}
	if(ge >= 3)
		return 0;
	else
		return 1;
}

//输出结果
void output(double result)
{
	printf("所得结果是: ");
	cout<<result<<endl;
}

//检查表达式是否合法
double check()
{
	void introduce();
	char cc;//决定计算器按哪种功能进行计算
	double result;//结果
	void input();//定义
	if( check_kuohao() && check_char() )//看是否合法, 合法则计算
	{
		result = compute();
		return result;
	}
	else//不合法,分两种不合法
	{
		if(check_kuohao() == 0 && check_char() == 1)
		{
			cout<<"您所输入的表达式括号不匹配, 请重新输入:"<<endl;
			input();//输入表达式
		}
		else
		{
			cout<<"您所输入的表达式不合法, 请重新输入:"<<endl;
			input();//输入表达式
		}
	}
}

//处理负号
void tackle_fuhao()
{
	node *root, *head, *p, *q, *p1;
	root = head = new node;
	head->next = NULL;
	int i;
	for(i = 0; line[i] != '\0'; i++)//建立链表
	{
		p = new node;
		p->data = line[i];
		p->next = head->next;
		head->next = p;
		head = p;
	}
	// delete p;
	q = (node*)malloc(sizeof(node));
	head = root;
	if(root->next->data == '+' || root->next->data == '-')//处理第一个字符
	{
		p = new node;
		p->data = '0';
		p->next = head->next;
		head->next = p;
	}
	if(root->next != NULL)
	{
		for(q = root->next; q; q = q->next)
		{
			if(q->data == '(' && (q->next->data == '-' || q->next->data == '+'))
			{
				p = new node;
				p->data = '0';
				p->next = q->next;
				q->next = p;
			}
		}
	}
	// delete q;
	p1 = new node;
	int qi = -1;
	for(p1 = root->next; p1; p1 = p1->next)
	{
		line[++qi] = p1->data;
	}
	line[++qi] = '\0';
}

//输入
void input()
{
    void introduce();
	cin>>judge;
	printf("请输入表达式:");
	cin>>line;
	if(judge==1){
        cnt=0;
        if(biao == 0)
		tackle_fuhao();//处理负号
		printf("所得结果:");
	    cout<<check()<<endl;//检查表达式是否合法
	}
	if(judge==2){
        cnt=1;
        int p=0,q=0,t=0,c=0,w;//w为1,2,3,4,5,6分别代表">","<","==","!=",">=","<="
        string line1,line2;
        double result1,result2;
        for(int i=0;i<line.size();i++){
            if(!t){
            if(line[i]=='>'&&line[i+1]!='='){
                t=1;
                c=1;
                w=1;
                i++;
            }
            if(line[i]=='<'&&line[i+1]!='='){
                t=1;
                c=1;
                w=2;
                i++;
            }
            if(line[i]=='='&&line[i+1]=='='){
                t=1;
                c=1;
                w=3;
                i+=2;
            }
            if(line[i]=='!'&&line[i+1]=='='){
                t=1;
                c=1;
                w=4;
                i+=2;
            }
            if(line[i]=='>'&&line[i+1]=='='){
                t=1;
                c=1;
                w=5;
                i+=2;
            }
            if(line[i]=='<'&&line[i+1]=='='){
                t=1;
                c=1;
                w=6;
                i+=2;
            }
            }
            if(!c)
               line1+=line[i];
            else
               line2+=line[i];
        }

        line=line1;
        if(biao == 0)
          tackle_fuhao();//处理负号
	    result1=check();//检查表达式是否合法
	    line=line2;
        if(biao == 0)
		  tackle_fuhao();//处理负号
	    result2=check();//检查表达式是否合法
        printf("所得结果:");
	    if(w==1&&result1>result2)
            printf("YES\n");
        else if(w==2&&result1<result2)
            printf("YES\n");
        else if(w==3&&result1==result2)
            printf("YES\n");
        else if(w==4&&result1!=result2)
            printf("YES\n");
        else if(w==5&&result1>=result2)
            printf("YES\n");
        else if(w==6&&result1<=result2)
            printf("YES\n");
        else
            printf("NO\n");
	}
	char cc;
	cout<<"输入一个字符'D'或'F',决定是否继续:"<<endl;
	while(cin>>cc){
        if(cc=='D'){
            system("cls");
            introduce();
            cout<<"计算机已清零!"<<endl<<"1.计算算术表达式"<<endl<<"2.判断关系表达式"<<endl;
            cout<<"请输入:";
            input();
            break;
        }
        else if(cc=='F'){
            system("cls");
            cout<<"计算机关闭,谢谢使用!"<<endl;
            break;
        }
	}
}

//对计算器的符号功能的简要介绍
void introduce()
{
	cout<<"\t计算器简要介绍"<<endl;
	cout<<"\t __________________________________________________________"<<endl;
	cout<<"\t|                                                          |"<<endl;
	cout<<"\t|C(cos)   S(sin)   T(tan)   c(arccos)   s(arcsin)          |"<<endl;
	cout<<"\t|7        8        9        /           on        t(arctan)|"<<endl;
	cout<<"\t|4        5        6        *           %         L(log)   |"<<endl;
	cout<<"\t|1        2        3        -           F(off)    Q(sqrt)  |"<<endl;
	cout<<"\t|0        .        +        ^(乘方)               Enter(=) |"<<endl;
	cout<<"\t|__________________________________________________________|"<<endl<<endl;;
	cout<<"\t对于对数输入 L2_5 表示以2为底5的对数"<<endl;
	//cout<<"M(在前面结果的基础上继续计算,如:上次结果为10,现输入+10.5*2)"<<endl;
	cout<<"\t  D (清零并继续输入)"<<endl;
	cout<<"\t  F (计算机关闭)"<<endl;
	cout<<"\t输入 P 就代表输入圆周率, 输入 E 代表输入自然对数"<<endl<<endl;
}

//界面
void print()
{
	system("color F7");     //设置默认控制台前景背景色  字体颜色(浅红)
	cout<<"      欢迎使用本计算器"<<endl;
	cout<<"输入一个字符串 on, 计算器开始启动"<<endl;
}

//是否启动计算器
void if_start()
{
	string start;

	print();
	system("color FC");
	while(cin>>start)
	{
		if(start != "on")
		{
			cout<<"您所输入的字符无效, 请按照介绍的继续输入:"<<endl;
			continue;
		}
		else
			break;
	}
	if(start == "on")
	{
		system("color F5");      //设置默认控制台前景背景色  字体颜色(紫)
		system("cls");    //清屏函数
	}
	introduce();//对计算器的简要介绍
	cout<<"现在,请输入您所要计算的算术表达式或判断的关系表达式"<<endl;
	cout<<"1.计算算术表达式"<<endl<<"2.判断关系表达式"<<endl;
	cout<<"请输入:";
    input();
}


//主函数
int main()
{
	if_start();//调用是否启动计算器函数

	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值