算符优先的思想实现一个简易计算器

先贴一个纯扫描方法的方案

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void add();                      //非实数加法 
void add1();                     //实数加法 
void sub();                      //非实数减法 
void sub1();                     //实数减法 
void mul();                      //非实数乘法 
void mul1();                     //实数乘法 
void chu();                      //非实数除法 
void chu1();                     //实数除法 
void mix();                      //非实数,不带括号
void mix1();                     //实数,不带括号
void mix2();                     //非实数,带括号
void mix3();                     //实数,带括号
double count(double num[][1001],char ch[][1001],int ,int ,int ,int );  
                                 //用于mix2,mix3,可以计算一对括号间表达式的值 
int flag2;                       //用于mix2,mix3,/后有0报错 

int main()
{
  int a,b;
  while(1)
  {
    printf("====================\n");
    printf("功能菜单:\n");
    printf("  1 加法\n");
    printf("  2 减法\n");
    printf("  3 乘法\n");
    printf("  4 除法\n");
    printf("  5 混合运算\n");
    printf("  6 带括号的混合运算\n");
    printf("  0 退出程序\n");
    printf("====================\n");
    printf("请选择:");
    scanf("%d",&a);
    getchar();                       //跳过回车
    switch(a)
    {
      case 1:
      {
        printf("  1 非实数\n  2 实数\n请选择:");
        scanf("%d",&b);
        getchar();
        if(b==1)add();
        if(b==2)add1();
      }break;
      case 2:
      {
        printf("  1 非实数\n  2 实数\n请选择:");
        scanf("%d",&b);
        getchar();
        if(b==1)sub();
        if(b==2)sub1();
      }break;
      case 3:
      {
        printf("  1 非实数\n  2 实数\n请选择:");
        scanf("%d",&b);
        getchar();
        if(b==1)mul();
        if(b==2)mul1();
      }break;
      case 4:
      {
        printf("  1 非实数\n  2 实数\n请选择:");
        scanf("%d",&b);
        getchar();
        if(b==1)chu();
        if(b==2)chu1();
      }break;
      case 5:
      {
        printf("  1 非实数\n  2 实数\n请选择:");
        scanf("%d",&b);
        getchar();
        if(b==1)mix();
        if(b==2)mix1();
      }break;
      case 6:{
      	printf("  1 非实数\n  2 实数\n请选择:");
      	scanf("%d",&b);
      	getchar();
      	if(b==1)mix2();
      	if(b==2)mix3();
		break;
	  }
      case 0:exit(0);

    }

  }

  return 0;
}

void add()
{
  int res = 0,_flag = 0;                    //_flag用于处理带负数的情况 
  int num;                     
  char ch;                                
  while( (ch=getchar()) != '=')
  {
  	if(ch=='\n') break;
  	if(ch=='(' || ch==')') continue;
	if(ch=='-')
	{
	  _flag = 1;
	  continue;	
	} 
    num = 0;
    while( ch>='0' && ch<='9' )
    {
      num = num*10+(ch-'0');
      ch = getchar();
    }
    if(_flag==1)
    {
      res -= num;
      _flag = 0;
	}
	else
	  res += num;
  }
  printf("%d\n",res);
}

void add1()
{
  double res = 0,num;
  int flag,z,_flag = 0;
  char ch;
  while( (ch=getchar()) != '=')
  {
  	if(ch=='\n') break;
  	if(ch=='(' || ch==')') continue;
	if(ch=='-')
	{
	  _flag = 1;
	  continue;	
	}
    num = 0;flag = 0;z = 0;
    while( ch>='0' && ch<='9' || ch=='.')           //解析实数
    {
      if(ch=='.')
      {
        flag = 1;
        ch = getchar();
        continue;
      }
      if(flag==0)
      {
        num = num*10+(ch-'0');
        ch = getchar();
      }
      else
      {
        z++;                              //记录循环次数
        num = (num*pow(10,z)+(ch-'0'))/pow(10,z);
        ch = getchar();
      }    
    }                                               //解析完毕
    if(_flag==1)
    {
      res -= num;
      _flag = 0;
	}
	else
	  res += num;

  }
  printf("%.2f\n",res);
}

void sub()
{
  int i = 1,_flag = 0;                 
  int res;
  int num;
  char ch;
  while( (ch=getchar()) != '=')
  {
  	if(ch=='\n') break;
  	if(i==1 && ch=='-')
  	{
  	  _flag = 1;
	  continue;	
	}
	if(ch=='(')
	{
	  _flag = 1;
	  getchar();
	  continue;
	}
	if(ch==')') continue;
    num = 0;
    while( ch>='0' && ch<='9' )
    {
      num = num*10+(ch-'0');
      ch = getchar();
    }
    if(_flag==1)
    {
    	num = -num;
    	_flag = 0;
	}
    if(i)                          // 首个num赋给res
    {
      res = num;
      i = 0;
    }
    else
      res -= num;

  }
  printf("%d\n",res);
}

void sub1()
{
  int i = 1;
  double res,num;
  int flag,z,_flag = 0;
  char ch;
  while( (ch=getchar()) != '=')
  {
  	if(ch=='\n') break;
  	if(i==1 && ch=='-')
  	{
  	  _flag = 1;
	  continue;	
	}
	if(ch=='(')
	{
	  _flag = 1;
	  getchar();
	  continue;
	}
	if(ch==')') continue;
    num = 0;flag = 0;z = 0;
    while( ch>='0' && ch<='9' || ch=='.')
    {
      if(ch=='.')
      {
        flag = 1;
        ch = getchar();
        continue;
      }
      if(flag==0)
      {
        num = num*10+(ch-'0');
        ch = getchar();
      }
      else
      {
        z++;                                //记录循环次数
        num = (num*pow(10,z)+(ch-'0'))/pow(10,z);
        ch = getchar();
      }    
    }
    if(_flag==1)
    {
      num = -num;
      _flag = 0;
	}
    if(i)                          // 首个num赋给res
    {
      res = num;
      i = 0;
    }
    else  
      res -= num;

  }
  printf("%.2f\n",res);
}

void mul()
{
  int res = 1,_flag = 0;
  int num;
  char ch;
  while( (ch=getchar()) != '=')
  {
  	if(ch=='\n') break;
  	if(ch=='(' || ch==')') continue;
	if(ch=='-')
	{
	  _flag = 1;
	  continue;	
	} 
    num = 0;
    while( ch>='0' && ch<='9' )
    {
      num = num*10+(ch-'0');
      ch = getchar();
    }
    if(_flag==1)
    {
      num = -num;
      _flag = 0;
	}
    res *= num;

  }
  printf("%d\n",res);
}

void mul1()
{
  double res = 1,num;
  int flag,z,_flag = 0;
  char ch;
  while( (ch=getchar()) != '=')
  {
  	if(ch=='\n') break;
  	if(ch=='(' || ch==')') continue;
	if(ch=='-')
	{
	  _flag = 1;
	  continue;	
	} 
    num = 0;flag = 0;z = 0;
    while( ch>='0' && ch<='9' || ch=='.')
    {
      if(ch=='.')
      {
        flag = 1;
        ch = getchar();
        continue;
      }
      if(flag==0)
      {
        num = num*10+(ch-'0');
        ch = getchar();
      }
      else
      {
        z++;                              //记录循环次数
        num = (num*pow(10,z)+(ch-'0'))/pow(10,z);
        ch = getchar();
      }    
    }
    if(_flag==1)
    {
    	num = -num;
    	_flag = 0;
	}
    res *= num;

  }
  printf("%.2f\n",res);
}

void chu()
{
  int i = 1,_flag = 0,flag3 = 0;                //flag3用来检验输入错误 
  double res;
  int num;
  char ch;
  while( (ch=getchar()) != '=' )
  {
  	if(ch=='\n') break;
  	if(ch=='-')
  	{
  	  _flag = 1;
	  continue;	
	}
	if(ch=='(' || ch==')') continue;
    num = 0;
    while( ch>='0' && ch<='9' )
    {
      num = num*10+(ch-'0');
      ch = getchar();
    }
    if(_flag==1)
    {
      num = -num;
      _flag = 0;
	}
    if(i)                          // 首个num赋给res
    {
      res = num;
      i = 0;
    }
    else
    {
      if( num == 0 )
      {
        flag3 = 1;
      }
      res /= num;
    }

  }
  if(flag3==1)
    printf("输入错误!!!\n");
  else
    printf("%.2f\n",res);
}

void chu1()
{
  int i = 1;
  double res = 0,num;
  int flag,z,_flag = 0,flag3 = 0;
  char ch;
  while( (ch=getchar()) != '=' )
  {
  	if(ch=='\n') break;
  	if(ch=='-')
  	{
  	  _flag = 1;
	  continue;	
	}
	if(ch=='(' || ch==')') continue;
    num = 0;flag = 0;z = 0;
    while( ch>='0' && ch<='9' || ch=='.')
    {
      if(ch=='.')
      {
        flag = 1;
        ch = getchar();
        continue;
      }
      if(flag==0)
      {
        num = num*10+(ch-'0');
        ch = getchar();
      }
      else
      {
        z++;                              //记录循环次数
        num = (num*pow(10,z)+(ch-'0'))/pow(10,z);
        ch = getchar();
      }    
    }
    if(_flag==1)
    {
      num = -num;
      _flag = 0;
	}
    if(i)                          // 首个num赋给res
    {
      res = num;
      i = 0;
    }
    else  
    if( num == 0 )
    {
        flag3 = 1;
    }
    res /= num;
  }
  if(flag3==1)
    printf("输入错误!!!\n");
  else
    printf("%.2f\n",res);
}

void mix()
{
  int i = 0,_flag = 0;
  int res;
  char ch;
  char a[1001];
  int num[1001];int j = 0;             //记录算完乘除后的剩余数字
  char b[1001]; int k = 0;             //记录运算符'+','-'
  int num1 = 0,num2;
  gets(a);
  if(a[0]=='-')
  {
  	_flag = 1;
  	i++;
  }
  while( a[i]>='0' && a[i]<='9')    
  { 
    num1 = num1*10+(a[i]-'0');
    i++;   
  }
  if(_flag==1)
  {
  	num1 = -num1;
  	_flag = 0;
  }
  while( a[i] != '=' )                //先算乘除
  { 
  	if(a[i]=='\n') break;
  	if(a[i]==')') i++;
    ch = a[i];
	i++;
    num2 = 0;
    if(a[i]=='(')
    {
      _flag = 1;
      i +=2;
	}
    while( a[i]>='0' && a[i]<='9')
    {
      num2 = num2*10+(a[i]-'0');
      i++;   
    }
    if(_flag==1)
    {
      num2 = -num2;
      _flag = 0;
	}
    switch(ch)
    {
      case '*':num1 *= num2;break;
      case '/':
      {
      	if(num2==0)
		{
      	  printf("数据错误!\n");
      	  return;
		}
      	num1 /= num2;
		break;
	  }
      case '+':{num[j++] = num1;num1 = num2;b[k++] = '+';break;}
      case '-':{num[j++] = num1;num1 = num2;b[k++] = '-';break;}
    } 
  }
  num[j] = num1;b[k] = '=';
  j = 0;k = 0;                       //后算加减
  res = num[0];
  while( b[k] != '=' )
  {
    j++;
    if( b[k++] == '+' )
      res += num[j];
    else
      res -= num[j];
  }
  printf("%d\n",res);
}

void mix1()
{
  int i = 0,flag = 0,z = 0,_flag = 0;
  double res = 0;
  char ch;
  char a[1001];
  double num[1001];int j = 0;             //记录算完乘除后的剩余数字
  char b[1001]; int k = 0;                //记录运算符'+','-'
  double num1 = 0,num2;
  gets(a);
  if(a[0]=='-')
  {
  	_flag = 1;
  	i++;
  }
  while( a[i]>='0' && a[i]<='9' || a[i]=='.')      //记录第一个数,赋给num1    
  { 
    if(a[i]=='.')
    {
      flag = 1;
      i++;
      continue;
    }
    if(flag==0)
    {
      num1 = num1*10+(a[i]-'0');
      i++;   
    }
    else
    {
      z++;
      num1 = (num1*pow(10,z)+(a[i]-'0'))/pow(10,z);
      i++;
    }
  }
  if(_flag==1)
  {
  	num1 = -num1;
  	_flag = 0;
  }  
  while( a[i] != '=' )                //先算乘除
  {
  	if(a[i]=='\n') break;
  	if(a[i]==')') i++; 
    ch = a[i];
    i++;
    if(a[i]=='(')
    {
      _flag = 1;
      i +=2;
	}
    num2 = 0;flag = 0;z = 0; 
    while( a[i]>='0' && a[i]<='9' || a[i]=='.')             
    {
      if(a[i]=='.')
      {
        flag = 1;
        i++;
        continue;
      }
      if(flag==0)
      {
        num2 = num2*10+(a[i]-'0');
        i++;   
      }
      else
      {
        z++;
        num2 = (num2*pow(10,z)+(a[i]-'0'))/pow(10,z);
        i++;
      }
    }
    if(_flag==1)
    {
      num2 = -num2;
      _flag = 0;
	}
    switch(ch)
    {
      case '*':num1 *= num2;break;
      case '/':
	  {
      	if(fabs(num2)<1e-6)
		{
      	  printf("数据错误!\n");
      	  return;
		}
      	num1 /= num2;
		break;
	  }
      case '+':{num[j++] = num1;num1 = num2;b[k++] = '+';break;}
      case '-':{num[j++] = num1;num1 = num2;b[k++] = '-';break;}
    } 
  }
  num[j] = num1;b[k] = '=';
  j = 0;k = 0;                       //后算加减
  res = num[0];
  while( b[k] != '=' )
  {
    j++;
    if( b[k++] == '+' )
      res += num[j];
    else
      res -= num[j];
  }
  printf("%.2f\n",res);
}

void mix2()
{            
  char a[1001];
  gets(a);
  flag2 = 0; 
  int i = 0,_flag = 0,t;
  int zuoKuo[2][1001];      int m = 0;           //记录左括号的位置和数量
  int youKuo[1001];         int n = -1;          //记录右括号的位置和数量
  double num[3][1001] = {0};int j = -1;          //记录解析后的数字大小,位置和数量
  char ch[3][1001] = {0};   int k = -1;          //记录运算符的种类,位置和数量
  if(a[0]=='-')
  {
  	_flag = 2;                                   //_flag=2,用来处理开头是负数的情况 
	i++; 
  }
  while(a[i]!='=')                               //开始记录
  {                                              //记录后,令字符串a[]左右两端模拟出一对括号 
  	if(a[i]=='\n') break;
    if(a[i]=='(')
    {
      if(a[i+1]=='-')
      {
      	_flag = 1;
      	t = i+1;
      	i++;
	  }
	  else
	  {
	  	m++;
        zuoKuo[0][m] = i+1;
	  }
	  i++;
	  continue;
    }
 
    if(a[i]==')')
    {
      if(_flag==1)
      {
      	_flag = 0;
	  }
	  else
	  {
	  	n++;
        youKuo[n] = i+1;
	  }
      i++;
      continue;
    }

    if(a[i]=='+' || a[i]=='-' || a[i]=='*' || a[i]=='/')
    {
      k++;
      ch[0][k] = a[i];
      ch[1][k] = i+1;
      i++;
      continue;
    }

    j++;
    num[1][j] = i+1;
    while(a[i]>='0' && a[i]<='9')
    {
      num[0][j] = num[0][j]*10+(a[i]-'0');
      i++;
    }
	if(_flag==1)
	{
	  num[0][j] = -num[0][j];
	}
	if(_flag==2)
	{
	  num[0][j] = -num[0][j];
	  _flag = 0;	
	}
	if(a[i]!=')' && _flag==1)
	{
	  m++;
	  zuoKuo[0][m] = t;
	  _flag = 0;
	}                                        

  }                                      //记录完毕
  zuoKuo[0][0] = 0;n++;youKuo[n] = i+1;  //使左右两端再带上一对括号 
                                         //左括号数m实际上等于右括号数n
  for(i=0;i<=j;i++)num[2][i] = 0;        //第三维,没用过用0表示,用过用1表示
  for(i=0;i<=k;i++) ch[2][i] = 0;
  for(i=0;i<=m;i++)zuoKuo[1][i] = 0;

  int flag;
  int num_s,num_e;
  int ch_s,ch_e;
  int p,kuo = n;                          //kuo保持原始括号数量 
  
  n = 0; 
  while(n<=kuo)
  {
  	m = kuo;
  	while(zuoKuo[1][m]==1) m--;           //把用过的左括号略过去 
  	while(zuoKuo[0][m]>youKuo[n]) m--;    //若左括号在右括号右边,则向左挑选左括号
	while(zuoKuo[1][m]==1) m--;           //把用过的左括号略过去  
  	
    flag = 0;
    for(p=0;p<=j;p++)                    //把介于zuoKuo[m]与youKuo[n]之间的num拉出来
    {                                    //记录下开始和结尾位置的数组下标num_s,num_e 
      if(num[1][p]>zuoKuo[0][m] && num[1][p]<youKuo[n])
      {
        if(flag == 0)
		{
		  flag = 1;
		  num_s = p;
		}
      }
      if(num[1][p]>youKuo[n])
	  {
		num_e = p-1;
        break;
      }
      if(p==j)
      {
      	num_e = p;
      	break;
	  }
	}
    
    flag = 0; 
    for(p=0;p<=k;p++)                    //把介于zuoKuo[m]与youKuo[n]之间的ch拉出来
    {                                    //记录下开始和结尾位置的数组下标ch_s,ch_e
      if(ch[1][p]>zuoKuo[0][m] && ch[1][p]<youKuo[n])
      {
        if(flag==0)
		{
		  flag = 1;
		  ch_s = p;
		}
      }
      if(ch[1][p]>youKuo[n])
	  {
		ch_e = p-1;
        break;
      }
      if(p==k)
      {
      	ch_e = p;
      	break;
	  }
    }
    
    num[0][num_s] = count(num,ch,num_s,num_e,ch_s,ch_e);
    zuoKuo[1][m] = 1;         //用过的括号标记为1 
    n++; 
  }
  if(flag2==0) 
    printf("%.2f\n",num[0][0]);
  else
    printf("数据错误!\n");

}

void mix3()
{
  char a[1001];
  gets(a);
  flag2 = 0;
  int i = 0,z = 0,t,flag1,_flag = 0;
  int zuoKuo[2][1001];      int m = 0;           //记录左括号的位置和数量
  int youKuo[1001];         int n = -1;          //记录右括号的位置和数量
  double num[3][1001] = {0};int j = -1;          //记录解析后的数字大小,位置和数量
  char ch[3][1001] = {0};   int k = -1;          //记录运算符的种类,位置和数量
  if(a[0]=='-')
  {
  	_flag = 2;
	i++; 
  }
  while(a[i]!='=')                               //开始记录
  {                                              //记录后,令字符串a[]左右两端模拟出一对括号 
    if(a[i]=='\n') break;
    if(a[i]=='(')
    {
      if(a[i+1]=='-')
      {
      	_flag = 1;
      	t = i+1;
      	i++;
	  }
	  else
	  {
	  	m++;
        zuoKuo[0][m] = i+1;
	  }
	  i++;
	  continue;
    }
 
    if(a[i]==')')
    {
      if(_flag==1)
      {
      	_flag = 0;
	  }
	  else
	  {
	  	n++;
        youKuo[n] = i+1;
	  }
      i++;
      continue;
    }

    if(a[i]=='+' || a[i]=='-' || a[i]=='*' || a[i]=='/')
    {
      k++;
      ch[0][k] = a[i];
      ch[1][k] = i+1;
      i++;
      continue;
    }

    j++;
    num[1][j] = i+1;
    flag1 = 0;
	z = 0;
    while(a[i]>='0' && a[i]<='9' || a[i]=='.')
    {
      if(a[i]=='.')
      {
        flag1 = 1;
        i++;
        continue;
      }
      if(flag1==0)
      {
        num[0][j] = num[0][j]*10+(a[i]-'0');
        i++;   
      }
      else
      {
        z++;
        num[0][j] = (num[0][j]*pow(10,z)+(a[i]-'0'))/pow(10,z);
        i++;
      }
    } 
	if(_flag==1)
	{
	  num[0][j] = -num[0][j];
	}
	if(_flag==2)
	{
	  num[0][j] = -num[0][j];
	  _flag = 0;
	}
	if(a[i]!=')' && _flag==1)
	{
	  m++;
	  zuoKuo[0][m] = t;
	  _flag = 0;	
	}                    

  }                                      //记录完毕
  zuoKuo[0][0] = 0;n++;youKuo[n] = i+1;  //使左右两端再带上一对括号 
                                         //左括号数m实际上等于右括号数n
  for(i=0;i<=j;i++)num[2][i] = 0;        //第三维,没用过用0表示,用过用1表示
  for(i=0;i<=k;i++) ch[2][i] = 0;
  for(i=0;i<=m;i++)zuoKuo[1][i] = 0;

  int flag;
  int num_s,num_e;
  int ch_s,ch_e;
  int p,kuo = n;                          //kuo保持原始括号数量 
  
  n = 0; 
  while(n<=kuo)
  {
  	m = kuo;
  	while(zuoKuo[1][m]==1) m--;           //把用过的左括号略过去 
  	while(zuoKuo[0][m]>youKuo[n]) m--;    //若左括号在右括号右边,则向左挑选左括号 
  	while(zuoKuo[1][m]==1) m--;           //把用过的左括号略过去 
  	
    flag = 0;
    for(p=0;p<=j;p++)                    //把介于zuoKuo[m]与youKuo[n]之间的num拉出来
    {                                    //记录下开始和结尾位置的数组下标num_s,num_e 
      if(num[1][p]>zuoKuo[0][m] && num[1][p]<youKuo[n])
      {
        if(flag == 0)
		{
		  flag = 1;
		  num_s = p;
		}
      }
      if(num[1][p]>youKuo[n])
	  {
		num_e = p-1;
        break;
      }
      if(p==j)
      {
      	num_e = p;
      	break;
	  }
	}
    
    flag = 0; 
    for(p=0;p<=k;p++)                    //把介于zuoKuo[m]与youKuo[n]之间的ch拉出来
    {                                    //记录下开始和结尾位置的数组下标ch_s,ch_e
      if(ch[1][p]>zuoKuo[0][m] && ch[1][p]<youKuo[n])
      {
        if(flag==0)
		{
		  flag = 1;
		  ch_s = p;
		}
      }
      if(ch[1][p]>youKuo[n])
	  {
		ch_e = p-1;
        break;
      }
      if(p==k)
      {
      	ch_e = p;
      	break;
	  }
    }
    
    num[0][num_s] = count(num,ch,num_s,num_e,ch_s,ch_e);
    zuoKuo[1][m] = 1;         //用过的括号标记为1 
    n++; 
  }
  if(flag2==0)
    printf("%.2f\n",num[0][0]);
  else 
    printf("数据错误!\n");	
}

double count(double num[3][1001],char ch[3][1001],int num_s,int num_e,int ch_s,int ch_e)
{
  int i = num_s,j = ch_s;          //i遍历num[0][],j遍历ch[0][]
  double x,y,z;
  char ch_1,ch_2;

  while(num[2][i]==1) i++;        //给x,y,ch_1赋值,规避掉已经用过的
  x = num[0][i];i++;
  while(num[2][i]==1) i++;
  y = num[0][i];i++;
  while(ch[2][j]==1)  j++;
  ch_1 = ch[0][j];j++;

  while(1)
  {
    while(num[2][i]==1) i++;            //把用过的数略过 
    while(ch[2][j]==1)  j++;             //把用过的运算符略过 
    if(i>num_e || j>ch_e) break;
    z = num[0][i];i++;
    ch_2 = ch[0][j];j++;
    
    if(ch_1=='*'||ch_1=='/' &&ch_2=='+'||ch_2=='-')    //比较ch_1和ch_2的优先级 
    {
      switch(ch_1)
      {	
        case '+':x += y;y = z;z = 0;break;
        case '-':x -= y;y = z;z = 0;break;
        case '*':x *= y;y = z;z = 0;break;
        case '/':
          if(fabs(y)<1e-6) flag2 = 1;
		  x /= y;y = z;z = 0;break;
      }
      ch_1 = ch_2;  
    }
    else
      switch(ch_2)
      {
    	case '+':y += z;z = 0;break;
        case '-':y -= z;z = 0;break;
        case '*':y *= z;z = 0;break;
        case '/':
          if(fabs(z)<1e-6) flag2 = 1;
		  y /= z;z = 0;break;
      }    

  }
  
  switch(ch_1)
  {	
    case '+':x += y;break;
    case '-':x -= y;break;
    case '*':x *= y;break;
    case '/':
      if(y==0) flag2 = 1;
      x /= y;break;
  }

  for(i=num_s+1;i<=num_e;i++) num[2][i] = 1;    //用过的数据标记一下;
  for(i=ch_s;i<=ch_e;i++)      ch[2][i] = 1;

  return x;
}

算符优先

思想:类似于编译原理中自下而上进行语法分析的算符优先分析法。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 1009
typedef double stack_num;
typedef char stack_ch;
char cmp[8][8]={'0','+','-','*','/','(',')','=',
                '+','>','>','<','<','<','>','>',
				'-','>','>','<','<','<','>','>',
				'*','>','>','>','>','<','>','>',
				'/','>','>','>','>','<','>','>',
				'(','<','<','<','<','<','=','0',
				')','>','>','>','>','0','>','>',
				'=','<','<','<','<','<','0','='};
double count();
char find(char,char);
double suan(double,double,char);
int main(){
	char a[MAX];
	double res;
	printf("输入一个算术表达式,以'='结尾\n");
	res = count();
	printf("%.2f\n",res);
	return 0;
}

double count(){
	double res = 0;            //res是最终结果 
	char ch1,ch2,rel;          //ch1是剩余表达式的首字符,ch2表示栈顶字符
	double num1,num2;
	int flag1 = 0,flag2,z;     //flag1标记负数,flag2标记小数 
	stack_num s1[MAX];         //数字栈 
	stack_ch s2[MAX];          //字符栈 
	int top1 = 0,top2 = 0;
	
	s2[top2++] = '=';
	ch1 = getchar();
	while(top2>0){             //字符栈不空 
		ch2 = s2[top2-1];
		//解析实数
		if(ch1=='-' && (ch2=='='||ch2=='(')){
			flag1 = 1;
			ch1 = getchar();
			continue;
		}
		else if(ch1>='0' && ch1<='9' || ch1=='.'){
			num1 = 0;flag2 = 0;z = 0;
    		while( ch1>='0' && ch1<='9' || ch1=='.'){        //解析实数
    			if(ch1=='.'){
    				flag2 = 1;
        			ch1 = getchar();
       				continue;
    			}
    			if(flag2==0){
        			num1 = num1*10+(ch1-'0');
        			ch1 = getchar();
    			}
    			else{
    				z++;                                   //记录循环次数
        			num1 = (num1*pow(10,z)+(ch1-'0'))/pow(10,z);
       				ch1 = getchar();
    			}    
  			}            
  			if(flag1==1){
    		num1 = -num1;
    		flag1 = 0;
			}                                        //解析完毕
			s1[top1++] = num1;
			continue;
		}
		else{
			rel = find(ch2,ch1);
			if(rel=='<'){
				s2[top2++] = ch1;
				ch1 = getchar();
				continue;
			}
			else if(rel=='>'){
				num2 = s1[--top1];
				num1 = s1[--top1];
				num1 = suan(num1,num2,ch2);
				s1[top1++] = num1;
				top2--;
				continue;
			}
			else if(rel=='='){
				top2--;
				ch1 = getchar();
				continue;
			}
			else{
				printf("输入的表达式有误!\n");
				exit(0);
			}
		}
	}
	if(top1<=0){
		printf("输入的表达式有误!\n");
		exit(0);
	}
	res = s1[top1-1];
	return res; 
}

char find(char ch2,char ch1){
	int i,j;
	for(i=1;i<8;i++)
		if(cmp[i][0]==ch2) break;
	for(j=1;j<8;j++)
		if(cmp[0][j]==ch1) break;
	return cmp[i][j];
}

double suan(double num1,double num2,char ch){
	switch(ch){
		case '+':num1 += num2;break;
		case '-':num1 -= num2;break;
		case '*':num1 *= num2;break;
		case '/':
			if(fabs(num2)<1e-6){
				printf("输入数据错误!\n"); 
				exit(0); 
			}
			num1 /= num2;
	}
	return num1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值