栈计算器c语言
1. 计算机c语言中 什么是栈和队列
栈(Stack)是仅限制在表的一端进行插入和删除运算的线性表,称插入、删除这一端为栈顶,另一端称为栈底。表中无元素时为空栈。栈 的修改是按后进先出的原则进行的,我们又称栈为LIFO表(Last In First Out)。通常栈有顺序栈和链栈两种存储结构。 栈的基本运算有六种: ·构造空栈:InitStack(S) ·判栈空: StackEmpty(S) ·判栈满: StackFull(S) ·进栈: Push(S,x) ·退栈: Pop(S) ·取栈顶元素:StackTop(S) 在顺序栈中有"上溢"和"下溢"的现象。 ·"上溢"是栈顶指针指出栈的外面是出错状态。 ·"下溢"可以表示栈为空栈,因此用来作为控制转移的条件。 顺序栈中的基本操作有六种:·构造空栈·判栈空·判栈满·进栈·退栈·取栈顶元素 链栈则没有上溢的限制,因此进栈不要判栈满。链栈不需要在头部附加头结点,只要有链表的头指针就可以了。 链栈中的基本操作有五种:·构造空栈·判栈空·进栈·退栈·取栈顶元素 队列(Queue)是一种运算受限的线性表,插入在表的一端进行,而删除在表的另一端进行,允许删除的一端称为队头(front),允许插入的 一端称为队尾(rear) ,队列的操作原则是先进先出的,又称作FIFO表(First In First Out) 。队列也有顺序存储和链式存储两种存储结 构。 队列的基本运算有六种: ·置空队:InitQueue(Q) ·判队空:QueueEmpty(Q) ·判队满:QueueFull(Q) ·入队:EnQueue(Q,x) ·出队:DeQueue(Q) ·取队头元素:QueueFront(Q) 顺序队列的"假上溢"现象:由于头尾指针不断前移,超出向量空间。这时整个向量空间及队列是空的却产生了"上溢"现象。 为了克服"假上溢"现象引入循环向量的概念,是把向量空间形成一个头尾相接的环形,这时队列称循环队列。 判定循环队列是空还是满,方法有三种: ·一种是另设一个布尔变量来判断; ·第二种是少用一个元素空间,入队时先测试((rear+1)%m = front)? 满:空; ·第三种就是用一个计数器记录队列中的元素的总数。 队列的链式存储结构称为链队列,一个链队列就是一个操作受限的单链表。为了便于在表尾进行插入(入队)的操作,在表尾增加一个尾指 针,一个链队列就由一个头指针和一个尾指针唯一地确定。链队列不存在队满和上溢的问题。在链队列的出队算法中,要注意当原队中只 有一个结点时,出队后要同进修改头尾指针并使队列变空。
2. 怎样用c语言编一个简单的计算器最简单的
//简单计算器,含加减乘除、乘方运算。
 #include<string.h>
 #include<ctype.h>
 #include<malloc.h> // malloc()等
 #include<limits.h> // INT_MAX等
 #include<stdio.h> // EOF(=^Z或F6),NULL
 #include<stdlib.h> // atoi()
 #include<io.h> // eof()
 #include<math.h> // floor(),ceil(),abs()
 #include<process.h> // exit()
 #include<iostream.h> // cout,cin
 // 函数结果状态代码
 #define TRUE 1
 #define FALSE 0
 #define OK 1
 #define ERROR 0
 #define INFEASIBLE -1
 // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
 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;
}//InitStack
Status DestroyStack(SqStack1 &S){
 //销毁栈S
 free(S.top);
 free(S.base);
 return OK;
}//DestroyStack
char GetTop(SqStack1 S){
 //若栈不空,则返回S的栈顶元素,并返回OK;否则返回ERROR
 if(S.top==S.base)return ERROR;
 return *(S.top-1);
}//Gettop
Status 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;
}//Push
Status Pop(SqStack1 &S,char &e){
 //若栈不空,则删除S的栈顶元素,用e返回其值;并返回OK;否则返回ERROR
 if(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;
}//InitStack
Status DestroyStack(SqStack2 &S){
 //销毁栈S
 free(S.top);
 free(S.base);
 return OK;
}//DestroyStack
float GetTop(SqStack2 S){
 //若栈不空,则返回S的栈顶元素,并返回OK;否则返回ERROR
 if(S.top==S.base)return ERROR;
 return *(S.top-1);
}//Gettop
Status 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;
}//Push
Status Pop(SqStack2 &S,float &e){
 //若栈不空,则删除S的栈顶元素,用e返回其值;并返回OK;否则返回ERROR
 if(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);
 }
}//Precede
Status InOP(char c){
 //判断c是否是运算符,是则返回TRUE,否则返回FALSE
 switch(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("分母不能为0!\n");
    exit(0);
   }
   else return a/b;
  case '^':
   if(a==0&&b<=0){
    printf("0的指数必须大于0!\n");
    exit(0);
   }
   else return (float)pow(a,b);
  default:printf("表达式错误!\n");exit(0);
 }
}//Operate
Status 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);}
  //若某“-”前面是“=”(第一个符号就是“-”)或“(”,则此为负号,不是减号
  else if(!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栈
  else
   switch(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;
}//EvaluateExpression
    
void main(){
 printf("                   **********************\n");
 printf("                   *   欢迎使用计算器!  *\n");
 printf("                   **********************\n");
 printf("请输入表达式,以“=”结束:\n");
 printf("(支持实数间的加(+)、减(-)、乘(*)、除(/)、乘方(^)、单目减(-)运算)\n");
 EvaluateExpression();
 exit (0);
}
