c语言 多功能计算器(利用栈实现)

#include<stdio.h>
#include<stdlib.h>
#define max 100 
void Name()//封面 
{
	printf("---------------------------------\n");
	printf("     这是一个简易的计算器\n");
	printf(" 请输入序号选择你要进行的操作:\n");
	printf("1.进制转换      2.算术表达计算\n");
	printf("0.退出程序\n");
	printf("---------------------------------\n");
}
typedef struct {
	int data[max];
	int top;
}SqStack;
SqStack* InitStack()//初始化栈 
{
	SqStack *s=(SqStack*)malloc(sizeof(SqStack));
	s->top=-1;//初始化栈顶指针 
	return s;
}
int StackEmpty(SqStack s){//判断栈是否为空 
	if(s.top==-1) return 1;//为空
	else return 0;//不为空 
}
int PushStack(SqStack *s,int x)//压栈操作 
{
	if(s->top==max-1) return 0;
		s->top++;
	s->data[s->top]=x;
	return 1;
 }
int PopStack(SqStack *s){//出栈操作 
    if(s->top==-1) return 0;
    return s->data[s->top--];
}
int Priority(char u)//判断运算符的优先级
{
	switch(u){
		case '+':
		case '-': return 1;
		case '*':
		case '/':return 2;
		default: return -1;
	}
}
void PopPush(SqStack *OPTR,SqStack *OPND)
{  //两操作数、操作符出栈,计算结果,结果入栈 
    char u;
    int x1,x2,sum;
    u=PopStack(OPTR);//将操作符出栈 
    x1=PopStack(OPND);//将两个操作数出栈 
    x2=PopStack(OPND);
    switch(u){//根据出栈操作符选择计算方式 
    	case '+':sum=x2+x1;break;
    	case '-':sum=x2-x1;break;
    	case '*':sum=x2*x1;break;
    	case '/':sum=x2/x1;break; 
	}
	PushStack(OPND,sum);//将计算得到的数 重新入操作数栈 
}
int Count(char *s)//扫描表达式并计算
{
	SqStack *OPTR,*OPND;//建立两个栈
	 OPTR=InitStack();// 分别初始化 
	 OPND=InitStack();
	 while(*s!='\0'){//扫描表达式直到扫描结束为止 
	 	if(*s>='0'&&*s<='9'){//扫描到数字 
	 	   int y= *s-'0';//将字符转为数字
	 		s++;//扫描的指针往下移 
	 		while(*s>='0'&&*s<='9') {//处理多位数 
	 		  y=y*10+*s-'0'; //最开始得到的元素往前移 
			    s++;//扫描指针往后移 
				}
			 PushStack(OPND,y);//入操作数栈 
		 }
		 else if(OPTR->top==-1||*s=='('||Priority(*s)>Priority(OPTR->data[OPTR->top])){//扫描到运算符 
		 //如果扫描的栈为空、左括号、运算符优先级>运算符栈顶优先级 
		 	PushStack(OPTR,*s);//则运算符压入运算符栈 
			 s++; //扫描的指针继续往下移 
			 if(*s=='-'){ //添加负号的情况 
			 	PushStack(OPND,0);//将0入操作数栈
			 }
		 }
		 else if(*s==')'&&OPTR->data[OPTR->top]=='('){
		 	//如果扫描到右括号且栈顶为左括号 
		 	PopStack(OPTR);//将左括号出栈 
		 	s++;//扫描的指针继续往下移 
		 }
		 else //扫描到的运算符优先级<=运算符栈顶优先级
		 PopPush(OPTR,OPND);//将进行计算操作 
	 }
	 while(OPTR->top>=0)//表达式扫描完成,将所有运算符出栈 
	  PopPush(OPTR,OPND);//并计算放入操作数栈 
	  int n=OPND->data[OPND->top];//将最后操作数进行出栈 
	  free(OPTR);//释放两栈 
	  free(OPND);
	 return n;//返回结果 
}
void Conversion1(int x,int y) //10进制转换2\4\8\16\32进制计算 
{
	SqStack *s=InitStack(); //创建一个栈并且初始化 
	char ch[50]; //创建一个字符数组用来输出进制结果(16进制中有字符) 
	int as,i=0;  //as为临时变量存放从栈中出来的元素 
	if(y==2||y==4||y==8||y==16||y==32){
	while(x!=0){ //辗转相除法 
		int a=x%y; //计算得到余数 
		PushStack(s,a); //将每次得到的余数入栈 
     	x=x/y; //将每次除数的结果作下一次的被除数 
     }
	while(!StackEmpty(*s)){//将栈中所有的元素出栈
		as=PopStack(s); //并用临时as存放元素 
		if(as<10){ //当出栈元素是10以下时 
			ch[i]=as+'0'; //将该整数元素转为对应的字符形式并储存在从ch[]字符中中 
			i++; //字符数组往后走 
		}
		else{ //当出栈元素>=10时 
			ch[i]=as+87; //将该元素转为对应的小写字母,同时储存在ch[]中 
			i++; 字符数组继续往后走 
		}
	}
	ch[i]='\0';//当所有元素出栈完毕并且重新储存在从ch[]的字符数组中时,让ch[]结束方便后续输出 
	puts(ch); //输出所有储存在ch[]中的字符 即对应的进制转换结果 
    }
    else
    printf("您选择转换的进制有误!\n");
}
void  Conversion(){//进制转换
 int x,n;
 printf("请输入一个十进制数:\n");
 scanf("%d",&x);
 printf("输入你想换的进制(2,4,8,16,32)\n"); 
 scanf("%d",&n);
 printf("转换后的数:\n");
 Conversion1(x,n);//引用进制转换计算函数 
}
int test(char *s){//判断输入表达式是否合法 
	while(*s!='\0'){
	   if(*s>='0'&&*s<='9'||*s=='('||*s==')'){
	   		   	s++;
				  }
	   	else if(*s=='*'||*s=='/'){//当连续*/时 
	   		s++;
	   		if(*s=='*'||*s=='/')
	   		return 0;
		   }
		else if(*s=='-'||*s=='+'){//当连续+-时 
			s++;
			if(*s=='-'||*s=='+')
			 return 0;
		}
	   else //当非数字、运算符等 
	   	return 0;
	}
	return 1;
}
int main()
{
	Name();//引用封面函数 
	char c[50];
	int x,flgh=1;
	while(flgh){
		printf("请输入你的选择 :\n");
		scanf("%d",&x);
	switch(x){
		case 0:flgh=0;system("cls");break;
		case 1:Conversion();break;//引用进制转换函数 
		case 2:printf("请输入你要计算的表达式:(如果是负数请加括号) \n");
		    getchar();//便于接下来表达式的输出
			gets(c);//输入计算表达值 
			if(test(c)==0){//判断表达式是否合法 
				printf("请输入正确的表达式!\n");
			}
			else
	        printf("计算都得到的:%s=%d\n",c,Count(c));
	        break;
	    default:printf("请输入正确的序号!\n");break; 
	        }
    }  
	system("pause"); 
	 return 0;
}

  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值