利用栈实现c语言计算器

合集下载

C语言实现计算器功能

C语言实现计算器功能

C语言实现计算器功能C语言计算器实现是一种基本的编程练习,可以结合简单的数学表达式解析和计算功能来实现一个基本的计算器。

以下是一个简单的示例,它可以接受用户输入的数学表达式并返回计算结果。

首先,我们需要包含标准输入/输出库(stdio.h)和字符串处理库(string.h)。

我们还需要定义一些函数来处理数学表达式的解析和计算。

```c#include <stdio.h>#include <string.h>//返回运算符的优先级int precedence(char op)if (op == '+' , op == '-')return 1;if (op == '*' , op == '/')return 2;return 0;//执行四则运算int calculate(int a, int b, char op)switch (op)case '+':return a + b;case '-':return a - b;case '*':return a * b;case '/':return a / b;}return 0;//解析数学表达式并计算结果int evaluate(char *expression)int i;//创建两个空栈,用于操作数和运算符int values[100];int top_values = -1;char ops[100];int top_ops = -1;//遍历表达式的每个字符for (i = 0; i < strlen(expression); i++)//如果字符是一个数字,将其解析为整数,并将其推到操作数栈中if (expression[i] >= '0' && expression[i] <= '9')int value = 0;while (i < strlen(expression) && expression[i] >= '0' && expression[i] <= '9')value = value * 10 + (expression[i] - '0');i++;}values[++top_values] = value;}//如果字符是一个左括号,将其推到运算符栈中else if (expression[i] == '(')ops[++top_ops] = expression[i];}//如果字符是一个右括号,执行所有高优先级的运算else if (expression[i] == ')')while (top_ops > -1 && ops[top_ops] != '(')int b = values[top_values--];int a = values[top_values--];char op = ops[top_ops--];values[++top_values] = calculate(a, b, op);}top_ops--;}//如果字符是一个运算符,执行所有高优先级的运算elsewhile (top_ops > -1 && precedence(ops[top_ops]) >= precedence(expression[i]))int b = values[top_values--];int a = values[top_values--];char op = ops[top_ops--];values[++top_values] = calculate(a, b, op);}ops[++top_ops] = expression[i];}}//执行剩余的运算while (top_ops > -1)int b = values[top_values--];int a = values[top_values--];char op = ops[top_ops--];values[++top_values] = calculate(a, b, op);}//返回最终结果return values[top_values];int mainchar expression[100];printf("请输入数学表达式:");scanf("%s", expression);int result = evaluate(expression);printf("结果:%d\n", result);return 0;```上面的代码使用了栈来解析和计算数学表达式。

栈实现计算器(简单四则运算)

栈实现计算器(简单四则运算)

栈实现计算器(简单四则运算)主要是通过定义⼀个数栈和⼀个符号栈,并根据给出的计算式进⾏拆分,循环判断是数字还是符号,考虑数字的连续性和符号计算的优先级,具体实现如下:package com.pangzi.stucture;public class calculator {public static void main(String[] args) {String expression = "50+9*9-7";//定义⼀个需要被扫描的表达式//创建两个栈,⼀个数栈,⼀个符号栈ArrayStack2 numStack = new ArrayStack2(10);ArrayStack2 operStack = new ArrayStack2(10);//定义需要的变量int index = 0;//定义⼀个指向数字和运算符的索引,扫描栈中的内容int num1 = 0;//定义第⼀个数字int num2 = 0;//定义第⼆个数字int oper = 0;//定义操作符int res = 0;//定义运算结果char ch = ' ';//将每次扫描得到的char保存⾄ch⾥⾯String keepNum = "";//⽤于拼接多位数//开始扫描表达式while(true){//依次得到expression中的每⼀个字符ch = expression.substring(index, index+1).charAt(0);//⽤substr获取长度为1的⼀个个字符串,然后通过charat转换为字符。

//判断字符是数字还是运算符,然后进⾏处理if(operStack.isOper(ch)){//如果ch是⼀个符号//判断符号栈是否为空if(!operStack.isEmpty()){//如果符号栈不为空,⽤ch和符号栈存在的运算符进⾏⽐较,如果ch的优先级⼩于等于栈中符号的优先级//就从数栈中弹出两个数字,进⾏运算并将得到的结果放⼊数栈,然后将ch⼊符号栈if(operStack.priority(ch) <= operStack.priority(operStack.peek())){num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = numStack.cal(num1, num2, oper);numStack.push(res);operStack.push(ch);}else{//如果当前操作符的优先级⼤于符号栈中的优先级,直接⼊符号栈operStack.push(ch);}}else{//如果符号栈为空,进⾏⼊栈操作operStack.push(ch);//将ch⼊符号栈}}else{//如果ch是数据的话,则直接⼊数栈//numStack.push(ch - 48);//根据ascii表换算//当处理多位数时,不能扫描到数字时就⽴即⼊栈,因为有可能是多位数//在处理时,应该在expression的表达式后⾯在扫描⼀位,如果是数继续扫描,如果是符合则停⽌。

C语言实现简易计算器(可作加减乘除)

C语言实现简易计算器(可作加减乘除)

C语⾔实现简易计算器(可作加减乘除)C语⾔实现简易计算器(加减乘除)计算器作为课设项⽬,已完成答辩,先将代码和思路(注释中)上传⼀篇博客已增添、修改、整理⾄⽆错且可正常运⾏虽使⽤了栈,但初学者可在初步了解栈和结构语法后理解代码#include <stdlib.h>#include <stdio.h>#include <string.h>#define IsDouble 0#define IsChar 1//_______________________________________________________________________________________________________________________________________________________ //1.⽀持浮点数和字符的栈typedef struct {char * buffer;int typesize;int top;int max;} stack;stack * CreateStack(int max, int typesize);//创建⼀个栈void DestroyStack(stack *);//释放栈的空间void ClearStack(stack *);//清空栈int Push(stack *, void *);//⼊栈int Pop(stack *, void *);//出栈int GetSize(stack *s);//得到栈的⼤⼩int GetTop(stack *, void *);//找到栈顶int IsEmpty(stack *);//判断是否为空栈,空则下溢int IsFull(stack *);//判断栈是否已满,满则溢出stack * CreateStack(int max, int typesize){stack * s = (stack*)malloc(sizeof(stack));//为栈s malloc内存if (!s) return 0;//为结构中buffer元素malloc内存s->buffer = (char *)malloc(sizeof(char) * max * typesize);if (!s->buffer) return 0;//初始化结构中的栈顶,最⼤值,类型⼤⼩s->top = -1;s->max = max;s->typesize = typesize;return s;}void DestroyStack(stack* s){free(s->buffer);//先释放buffer的空间free(s);//在释放s的空间}void ClearStack(stack * s){s->top = -1;//清空栈(栈头位置归零)}int Push(stack * s, void * data){if (IsFull(s)) return 0;//如果栈已满则return 0,防⽌溢出//栈未满则将栈头移动打动下⼀位置,并将data中的元素拷⼊栈中buffer的第top位置s->top++;memcpy(s->buffer + s->top*s->typesize, data, s->typesize);//⼊栈成功return 1return 1;}int Pop(stack * s, void * data){if (IsEmpty(s)) return 0;//出栈判断栈是否为空,若为空则return 0//栈未空则将buffer中top位置的字符拷⼊data记录,并让栈头向前移动⼀个位置memcpy(data, s->buffer + s->top*s->typesize, s->typesize);s->top--;//成功则return 1return 1;}int GetSize(stack *s){return s -> top+1;//栈头位置+1得到⼤⼩}int GetTop(stack *s, void * data){if (IsEmpty(s)) return 0;//如果栈空return 0//栈不为空则将top位置的字符拷回data记录,得到栈头memcpy(data, s->buffer + s->top*s->typesize, s->typesize);//成功则return 1;return 1;}int IsEmpty(stack * s){return s->top == -1;//如果top为-1则栈空}int IsFull(stack * s){return s->top == s->max-1;//如果top为max-1则栈满}//___________________________________________________________________________________________________________________________________________________ //2.定义⼀个cal类型,其中data存数时sign为IsDouble,存字符时,sign为Ischartypedef struct {double data;char sign;} cal;//3.查找对应符号(找到则返回该符号下标)(找不到则说明该部分为数字返回-1)int SearchCode(char ch){char * code = "+-*/()@";//@为终⽌符,算式输⼊结束int index = 0;//while (code[index]){if (code[index] == ch) return index;index++;}return -1;}//4.得到两个符号间的优先级//与SearchCode相对应,char GetPriority(char ch, char next){//创建⼀个perferen表,第i⾏(列)对应SearchCode函数中code中的第i个字符char perferen[7][7] = {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=E",">>>>E>>","<<<<<E="};//找到两个形参对应的字符int c = SearchCode(ch);int n = SearchCode(next);//如果找不到对应运算符(字符不是运算符⽽是为数字)return Eif (c==-1 || n==-1) return 'E';//如果找到两个对应运算符则按照优先级表返回两个运算符的优先级return perferen[c][n];}//5.四则运算double add(double a, double b) { return a+b; }double sub(double a, double b) { return a-b; }double mul(double a, double b) { return a*b; }double ddiv(double a, double b) { return a/b; }//整合四种运算double calcu(double a, char ch, double b){double (*calculation[4])(double,double) = {add,sub,mul,ddiv};return calculation[SearchCode(ch)](a,b);}//6.检测字符串int CheckStr(char * buffer){int n;//遍历字符串确保算式中⽆⾮法字符若检测到⾮法字符return 0,若都合法则return 1for (n = 0;buffer[n];n++){if ((SearchCode(buffer[n]) != -1 || buffer[n] == '.' || (buffer[n] >= '0' && buffer[n] <= '9')) && buffer[n] != '@') continue;else return 0;}buffer[n] = '@';//加上终⽌符,表⽰算式结束buffer[n+1] = '\0';return 1;}//7.得到数据转化为double类型存⼊rsint GetDigit(char * buffer, int * n, double * rs){char str[30];int i,j = 0;for (i = 0;SearchCode(buffer[*n]) == -1;i++){str[i] = buffer[*n];//从*n位置开始,将这⼀串数字字符存⼊str(*n)++;}str[i] = '\0';for (i = 0;str[i];i++){if (str[i] == '.') j++;}//如果⼀段⼩数有多个⼩数点或⼩数点在数字⾸尾,return 0if (j>1 || str[i-1] == '.' || str[0] == '.') return 0;//rs接收转化为double的数据*rs = atof(str);//操作成功return 1return 1;}//8.将⽤户输⼊的buffer字符串转化为可供程序运算的calstr数组int resolu(char * buffer, cal * calstr){int i = 0, j = 0;cal c;while (buffer[i]){if (SearchCode(buffer[i]) == -1){//如果得到数据不成功则return 0if (GetDigit(buffer,&i, &c.data) == 0) return 0;//如果成功得到数据则在c.sign标记为浮点数c.sign = IsDouble;//将c存⼊数组calstr中calstr[j++] = c;}else{//若符号为运算符//判断正负号if (buffer[i] == '-' && (buffer[i-1] == '('||buffer[i-1] == '+'||buffer[i-1] == '-'||buffer[i-1] == '*'||buffer[i-1] == '/') || (i==0 && buffer[0] == '-')){ i++;if (GetDigit(buffer,&i, &c.data) == 0) return 0;//在符号的下⼀位开始查找,若找不到数字return 0//否则,给数字取相反数,c.sign标记为浮点数,存⼊calstr中c.data = 0 - c.data;c.sign = IsDouble;calstr[j++] = c;} else//如果是正号,与符号处理⽅式同理if (buffer[i] == '+' && (buffer[i-1] == '('||buffer[i-1] == '+'||buffer[i-1] == '-'||buffer[i-1] == '*'||buffer[i-1] == '/') || (i==0 && buffer[0] == '+')){ i++;if (GetDigit(buffer, &i, &c.data) == 0) return 0;c.sign = IsDouble;calstr[j++] = c;}else{//如果不是正负号,则为运算符,先强制转换为double类型存在c.data⾥,然后c.sign标记为char类型,存⼊calstrc.data = (double)buffer[i++];c.sign = IsChar;calstr[j++] = c;}}}//操作蔡成功则return 1return 1;}//9.计算出结果int result(cal * calstr, double * rs){stack * pst = CreateStack(100,sizeof(char));//运算符栈stack * pnd = CreateStack(100,sizeof(double));//数据栈double num1,num2;int n = 0;char ch = '@';Push(pst, &ch);//在转换得到的calstr中遍历直到终⽌符'@"while(ch != '@' || !(calstr[n].sign == IsChar && (char)calstr[n].data == '@')){//如果calstr的n位上是浮点数,则将这个data压栈进⼊数据栈pnd中if (calstr[n].sign == IsDouble){Push(pnd, &(calstr[n].data));n++;}//反之,如果是运算符,则要检测优先级else{switch( GetPriority(ch, (char)calstr[n].data)){//如果运算符优先级较⼩,则让ch等于优先级⼤的符号并压⼊符号栈pst中case '<':ch = (char)calstr[n].data;Push(pst, &ch);n++;break;//如果结果为等号,让符号出栈暂存到ch中case '=':if (!Pop(pst, &ch)) return 0;n++;break;//如果ch优先级较⾼,则将前两个数字及运算符出栈,分别储存⾄num2,ch,num1中,进⾏运算,得到的结果再次压栈进⼊pnd中 case '>':if (!(Pop(pnd,&num2) && Pop(pst,&ch) && Pop(pnd,&num1))) return 0;num1 = calcu(num1,ch,num2);Push(pnd, &num1);break;//如果符号顺序出错,return 0case 'E':return 0;}}//检测是否可以得到栈顶符号,栈空则return 0if (!GetTop(pst, &ch)) return 0;}//如果栈中得到了最终结果,并且取出pnd中的最终结果到rs,return 1if (GetSize(pnd) == 1 && GetTop(pnd,rs)){DestroyStack(pst);DestroyStack(pnd);return 1;}//否则 return 0else{return 0;}}//10.⽤户交互函数void treatment(){char buffer[100];//⽤户输⼊的字符串(算式)cal calstr[50];//计算⽤的数组double rs = 0;//计算结果printf("Enter your equation:");gets(buffer);//让⽤户输⼊算式buffer//⽤户不输⼊"exit"就不退出while (!(buffer[0]=='e' && buffer[1]=='x' && buffer[2]=='i' && buffer[3]=='t')){//检查buffer中字符君合法,成功将buffer转化为⽤于计算的calstr数组,成功计算出结果存⼊rsif (CheckStr(buffer) && resolu(buffer,calstr) && result(calstr,&rs)){printf("\n%lf\n",rs);}else{printf("\nError!\n");}printf("Enter \"exit\"to quit");printf("\nEnter your equation:");gets(buffer);//再次让⽤户输⼊算式}printf("\nbye\n");}//11.主函数int main(){treatment();}参考⽂献链接如下[参考⽂献]()。

C语言简易计算器的实现

C语言简易计算器的实现

C语言简易计算器的实现C语言简易计算器是一种用于进行基本数学运算的程序。

实现一个简易计算器的关键是要能够解析用户输入的数学表达式,并将其转化为计算机可以理解的形式,然后进行计算,并输出结果。

下面是一个大约1200字以上的示例实现。

```c#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <ctype.h>#define MAX_SIZE 100//定义操作符的优先级int getPriority(char op)if (op == '+' , op == '-')return 1;else if (op == '*' , op == '/')return 2;elsereturn 0;//进行四则运算int calculate(int a, int b, char op)switch (op)case '+': return a + b;case '-': return a - b;case '*': return a * b;case '/': return a / b;default: return 0;}//将中缀表达式转换为后缀表达式void infixToPostfix(char* infixExp, char* postfixExp) char stack[MAX_SIZE];int top = -1;int j = 0;for (int i = 0; infixExp[i] != '\0'; i++)if (isdigit(infixExp[i])) { // 数字直接输出到后缀表达式while (isdigit(infixExp[i]))postfixExp[j++] = infixExp[i++];}postfixExp[j++] = ' ';i--;}else if (infixExp[i] == '(') { // 左括号压入栈stack[++top] = infixExp[i];}else if (infixExp[i] == ')') { // 右括号弹出栈内所有操作符并输出到后缀表达式,直到遇到左括号while (top != -1 && stack[top] != '(')postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';}top--; // 弹出栈顶的左括号}else { // 操作符while (top != -1 && getPriority(stack[top]) >=getPriority(infixExp[i]))postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';stack[++top] = infixExp[i];}}while (top != -1) { // 将栈内剩余操作符弹出并输出到后缀表达式postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';}postfixExp[j] = '\0';//计算后缀表达式的值int evaluatePostfix(char* postfixExp)char stack[MAX_SIZE];int top = -1;for (int i = 0; postfixExp[i] != '\0'; i++)if (isdigit(postfixExp[i])) { // 数字压入栈int num = 0;while (isdigit(postfixExp[i]))num = num * 10 + (postfixExp[i++] - '0');stack[++top] = num;i--;}else if (postfixExp[i] == ' ')continue;}else { // 操作符,弹出栈顶的两个数进行计算,并将结果压入栈int b = stack[top--];int a = stack[top--];int result = calculate(a, b, postfixExp[i]);stack[++top] = result;}}return stack[top];int maichar infixExp[MAX_SIZE];printf("请输入中缀表达式:");fgets(infixExp, sizeof(infixExp), stdin); // 读取用户输入//将中缀表达式转换为后缀表达式char postfixExp[MAX_SIZE];infixToPostfix(infixExp, postfixExp);printf("后缀表达式为:%s\n", postfixExp);//计算后缀表达式的值并输出int result = evaluatePostfix(postfixExp);printf("计算结果为:%d\n", result);return 0;```这个简易计算器的实现基于栈的数据结构。

C语言堆栈计算器

C语言堆栈计算器

#include"stdafx.h"#include<string.h>#include<ctype.h>#include<malloc.h>// malloc()等#include<limits.h>// INT_MAX等#include<io.h>// eof()#include<math.h>// floor(),ceil(),abs()#include<process.h>// exit()#include<iostream>// cout,cin// 函数结果状态代码#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为,故去掉此行typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE#define STACK_INIT_SIZE 100#define STACKINCREMENT 10//*************************************************************************** //栈的储存结构typedef struct{//运算符栈char *base;char *top;int stacksize;}SqStack1;typedef struct{//运算数栈float *base;float *top;int stacksize;}SqStack2;//*************************************************************************** //以下是运算符栈的基本操作函数Status InitStack(SqStack1 &S){//初始化一个栈S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}//InitStackStatus DestroyStack(SqStack1 &S){//销毁栈Sfree(S.top);free(S.base);return OK;}//DestroyStackchar GetTop(SqStack1 S){//若栈不空,则返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;return *(S.top-1);}//GettopStatus Push(SqStack1 &S,char e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){//栈满,追加储存空间S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;}//PushStatus Pop(SqStack1 &S,char &e){//若栈不空,则删除S的栈顶元素,用e返回其值;并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;e=*(--S.top);return OK;}//Pop//*************************************************************************** //以下是运算数栈的基本操作函数Status InitStack(SqStack2 &S){//初始化一个栈S.base=(float *)malloc(STACK_INIT_SIZE*sizeof(float));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}//InitStackStatus DestroyStack(SqStack2 &S){//销毁栈Sfree(S.top);free(S.base);return OK;}//DestroyStackfloat GetTop(SqStack2 S){//若栈不空,则返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;return *(S.top-1);}//GettopStatus Push(SqStack2 &S,float e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){//栈满,追加储存空间S.base=(float *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(float));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;}//PushStatus Pop(SqStack2 &S,float &e){//若栈不空,则删除S的栈顶元素,用e返回其值;并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;e=*(--S.top);return OK;}//Pop//*************************************************************************** //以下是相关的运算符判断函数char Precede(char A,char B){//比较运算符A, B的优先关系,A,B的范围仅限于'+','-','*','/','^','(',')','=' //返回'>','<','='switch(A){case'+':switch(B){case'+':return'>';case'-':return'>';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0);}case'-':switch(B){case'+':return'>';case'-':return'>';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0);}case'*':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0);}case'/':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0); }case'^':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'>';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0); }case'(':switch(B){case'+':return'<';case'-':return'<';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':return'=';case'=':printf("表达式错误!\n");exit(0);default:printf("表达式错误!\n");exit(0); }case')':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'>';case'(':printf("表达式错误!\n");exit(0);case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0); }case'=':switch(B){case'+':return'<';case'-':return'<';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':printf("表达式错误!\n");exit(0);case'=':return'=';default:printf("表达式错误!\n");exit(0);}default:printf("表达式错误!\n");exit(0);}}//PrecedeStatus InOP(char c){//判断c是否是运算符,是则返回TRUE,否则返回FALSEswitch(c){case'+':return TRUE;case'-':return TRUE;case'*':return TRUE;case'/':return TRUE;case'^':return TRUE;case'(':return TRUE;case')':return TRUE;case'=':return TRUE;default:return FALSE;}}//InOP//***************************************************************************float Operate(float a,char theta,float b){switch(theta){case'+':return a+b;case'-':return a-b;case'*':return a*b;case'/':if(b==0){printf("分母不能为!\n");exit(0);}else return a/b;case'^':if(a==0&&b<=0){printf("0的指数必须大于!\n");exit(0);}else return (float)pow(a,b);default:printf("表达式错误!\n");exit(0);}//OperateStatus EvaluateExpression(){//算术表达式求值char c,x,theta,prec;//c是每次读取的字符,x是存放脱括号后的多余的括号,theta是运算符,prec是c的前一个字符float a,b,result;//a、b是每次从运算数栈中取出的要进行运算的数,result存放最终结果float cc,flag,ii,minus=1;//cc存放由字符串转化而来的浮点数,flag用于标记是否已读取过小数点,//ii存放小数部分需要缩小的倍数,minus用于记录该数前是否有负号SqStack1 OPTR;SqStack2 OPND;InitStack(OPTR);InitStack(OPND);Push(OPTR,'=');prec='=';scanf("%c",&c);while(c!='='||GetTop(OPTR)!='='){cc=0;flag=0;ii=10;if(c=='-'&&(prec=='='||prec=='(')){minus=-1;prec=c;scanf("%c",&c);}//若某“-”前面是“=”(第一个符号就是“-”)或“(”,则此为负号,不是减号elseif(!InOP(c)){while(!InOP(c)){if(c>=48&&c<=57){if(flag==0)cc=cc*10+c-48;//小数点之前else if(flag==1){cc=cc+(c-48)/ii;ii*=10;}//小数点之后else {printf("小数点错误!\n");exit(0);}//小数点有错}else if(c=='.')flag++;//读到小数点else {printf("表达式错误!\n");exit(0);}prec=c;scanf("%c",&c);}cc*=minus;minus=1;Push(OPND,cc);}//不是运算符则进OPND栈elseswitch(Precede(GetTop(OPTR),c)){case'<':Push(OPTR,c);prec=c;scanf("%c",&c);break;//栈顶元素优先级低case'=':Pop(OPTR,x);prec=c;scanf("%c",&c);break;//脱括号并接收下一字符case'>'://退栈并将运算结果入栈Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,theta,b));break;}result=GetTop(OPND);printf("%f\n",result);//DestroyStack(OPTR);//DestroyStack(OPND);return OK;}//EvaluateExpressionvoid main(){printf(" **********************\n");printf(" * 欢迎使用计算器! *\n");printf(" **********************\n");printf("请输入表达式,以“=”结束:\n");printf("(支持实数间的加(+)、减(-)、乘(*)、除(/)、乘方(^)、单目减(-)运算)\n"); EvaluateExpression();exit (0);}。

C语言简单计算器原理——表达式求值(采用逆波兰表达式和栈结合)

C语言简单计算器原理——表达式求值(采用逆波兰表达式和栈结合)

C语⾔简单计算器原理——表达式求值(采⽤逆波兰表达式和栈
结合)
表达式的求解的关键是将其转换成逆波兰表达式(即后缀表达式,如1+2*3它的逆波兰表达式为123*+),在后缀表达式中已经考虑了运算符的优先级,
没有括号,只有操作数和运算符。

算术表达式转换成后缀表达式⽅法如下:
依次从键盘输⼊表达式的字符ch,对于每个ch:
(1)若ch为数字则直接将其放⼊后缀数组exp中并以#号标记数值串结束。

(2)若ch为"(",则直接将其压⼊字符栈op中。

(3)若ch为")",则将栈中"("以前的字符依次全部删除并将其放⼊后缀数组exp中,然后再将字符ch放⼊字符栈op中。

(4)若ch为"+"."-",则将栈中"("以前的运算符依次全部删除并将其放⼊后缀数组exp中,然后再将ch放⼊op栈中。

(5)若ch为"*"."/",则将栈顶连续的"*"."/"删除,并放⼊后缀数组exp中,然后将ch放⼊op栈中。

(6)若字符串str扫描完毕,则将栈中所有运算符删除并放⼊后缀数组exp,最后在后缀数组exp中便可得到后缀表达式。

在对后缀表达式求值时要⽤到⼀个数值栈st,在后缀数组exp中从头开始扫描,若是数字则将其放⼊数值栈中,
若遇到字符就进⾏两次退栈,并将运算结果再放⼊栈中,如此重复下去,最后当后缀数组扫描完后数值栈st的栈顶元素便是所要求的表达式的值。

用C实现计算器

用C实现计算器
{
link top;//去栈顶元素
if(stack!=NULL)
{
top=stack;
stack=stack->next;
*num=top->date;
free(top);
return stack;
}
else
*num=0;
}
//判断栈是否为空
number=pull(number,&sum);
cout<<expression<<"="<<sum<<endl;
}
{ while(symble->date!='(')
{ number=pull(number,&num1);
number=pull(number,&num2);
symble=pull(symble,&sym);
number=push(number,tuo_result(sym,num1,num2),-1);
int position=0;//表达式的位置
int sym=0;//运算符
int num1=0;//后操作数
int num2=0;//前操作数
int sum=0;//运算结果
cout<<"请输入表达式:"<<endl;
gets(expression);
while(expression[position]!='\0' && expression[position]!='\n')
if(!empty(symble))//判断是否为空

C语言数据结构栈计算器的实现 课题设计报告书

C语言数据结构栈计算器的实现 课题设计报告书

目录1、课程设计任务 (1)2、需求分析 (1)3、概要设计………………………………………………………………………………1~24、详细设计………………………………………………………………………………3~55、小结 (5)课程设计任务·利用堆栈设计一个计算器。

需求分析·首先,以字符列的形式,从终端输入语法正确、不含变量的整数表达式。

利用已知的运算符优先关系,实现对算术四则混合运算表达式的求值。

·对该程序而言,主要的利用应是栈,并将运算的先后步骤经分析后实现为简单运算。

·不同于单纯表达式的运算,计算器有直接计算最近输入数据的特性,故只需一个栈对其进行操作数和操作符的存储即可。

·除通常的四则运算(加减乘除)外,计算器还应有求相反数、百分数、开根、倒数等功能。

概要设计·由于运算符有优先级别之差,所以一个表达式的运算不可能总是从左至右的循序执行。

每次操作的数据或运算符都是最近输入的,这与栈的特性相吻合,故本程序借助栈来实现按操作符的优先级完成表达式的求值计算。

算法概要:1、栈的抽象数据定义:ADT SqStack{数据对象:D={a i| a i∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={<a i-1,a i>| a i-1,a i∈D,i=1,2,3,……,n}约定其中a i端为栈底,a n端为栈顶。

2、栈的实现和操作集合:为不同于C# 编译库中自带的类库Stack<T>,这里使用CStack<T>进行区分。

classCStack<T>{privateintp_index;privateArrayList list;public CStack()/*初始化*/{list = new ArrayList();p_index = -1;}publicint Count{get{returnlist.Count;}}public void Push(object item)/*入栈*/{list.Add(item);p_index++;}public object Pop()/*出栈*/{objectobj = list[p_index];list.RemoveAt(p_index);p_index--;returnobj;}}3、运算:计算器在输入一个操作符后,文本框内的数据会清空,故只需一个栈即可完成相应的运算。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

栈的应用:C实现简单计算器(表达式的计算)
作为栈的著名应用,表达式的计算可以用下面方法实现:
首先建立两个栈,操作数栈NUM_S和运算符栈OPR_S。

其中,操作数栈用来存储表达式中的操作数;运算符栈用来存储表达式中的运算符。

可以用字符‘=’来表示表达式结束符。

自左至右的扫描待处理的表达式,并假设当前扫描到的符号为W,根据不同的符号W 做如下不同的处理:
1.若W为操作数,则将W压入操作数栈NUM_S,且继续扫描下一个字符;
2.若W为运算符,则根据运算符的性质做相应的处理:
(0)若符号栈为空,无条件入栈当前指针指向的字符
(1)若w为不大于运算符栈栈顶的运算符,则从操作数栈NUM_S中弹出两个操作数,设先后弹出的操作数为a、b,再从运算符栈
OPR_S中弹出一个运算符,比如为+,然后作运算a+b,并将运算结果压入操作数栈NUM_S。

(2)若w为左括号或者运算符的优先级大于运算符栈栈顶的运算符,则将运算符W 压入运算符栈OPR_S,并继续扫描下一个字符。

(3)若运算符W为右括号,循环操作(设先后弹出的操作数为a、b,再从运算符栈OPR_S中弹出一个运算符,比如为+,然后作运
算a+b, 并将运算结果压入操作数栈NUM_S),直到从运算符栈中弹出第一个左括号。

(4)若运算符W为表达式结束符‘=’,循环操作(设先后弹出的操作数为a、b,再从运算符栈OPR_S中弹出一个运算符,比如为
+,然后作运算a+b, 并将运算结果压入操作数栈NUM_S),直到运算符栈为空为止。

此时,操作数栈栈顶元素即为表达式的
值。

====================================================================== ===
举例:计算3+(5-2*3)/4-2=
(1)开始栈为空,3入栈,+入栈,(无条件入栈,5入栈,-号优先级比(高,所以-号入栈,2入栈,*优先级比目前栈顶的-号优先级高,所以*入栈,3入栈,接着扫描到)括号,)括号不入栈
| | | |
--------- ----------
| 3 | | * |
--------- ----------
| 2 | | - |
--------- ----------
| 5 | | ( |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(2)在)括号碰到(括号之前,让操作数栈一直出栈,直到让左括号出栈为止所以:2,3弹出操作数栈,*弹出操作符号栈,计算2*3 = 6,然后将6入操作数栈
| | | |
--------- ----------
| | | |
--------- ----------
| 6 | | - |
--------- ----------
| 5 | | ( |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(3)接着6,5弹出操作数栈,-弹出操作符栈,计算5-6 = -1,然后将-1入操作数栈,然后左括号出栈
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| -1 | | |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(4)接着向下遍历表达式,到/号,优先级比操作符栈栈顶+高,所以/压栈,然后接着扫描,4入栈,再接着扫描到-号,优先级比操作符栈栈顶/的优先级低,则操作数栈4,-1出栈,操作符栈/出栈,计算-1/4 = 0,
| | | |
--------- ----------
| | | |
--------- ----------
| 4 | | |
--------- ----------
| -1 | | / |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(5)将上一步结果0压入操作数栈,刚才扫描到的-号,优先级和+号相同,则-号不入栈,将0,3弹出,将+号弹出,
计算3+0 = 3
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| 0 | | |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(6)将上一步中的结果3压入操作数栈,-号入操作符栈,接着扫描到2,2入操作数栈,接着扫描,发现到了=号,则操作数栈2,3弹出,操作符栈-号弹出,计算3-2 = 1
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| 2 | | |
--------- ----------
| 3 | | - |
--------- ----------
操作数栈操作符栈
(7)将上一步中的结果1压入操作数栈,最后1弹出栈,作为最后结果。

| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| 1 | | |
--------- ----------
操作数栈操作符栈
//=========================== 完
==================================//。

相关文档
最新文档