#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;
}
c语言 多功能计算器(利用栈实现)
于 2023-05-13 21:11:21 首次发布
该程序是一个使用C语言编写的简易计算器,支持进制转换和算术表达式计算。它通过栈来处理运算符的优先级,实现括号内的表达式计算,以及10进制到2、4、8、16、32进制的转换。用户可以输入选择进行相应的操作,如输入表达式或选择进制转换。
摘要由CSDN通过智能技术生成