简易计算器

随便写的一个计算算术表达式的程序,支持正数,+,-,*/,()运算符。

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

#define Maxsize 81

/* 运算符栈 */
struct stack_oper
{
    char  oper[Maxsize];
    int   top;
}operstack;

/* 数据栈 */
struct stack_data
{
    float  data[Maxsize];
    int    top;
}datastack;

char pop_stack_oper(struct stack_oper *p_operstack)
{
 char temp;
 
 if (p_operstack->top >= 0)
 {
  temp = (p_operstack -> oper)[p_operstack->top];
 }
 else
 {
  fprintf(stderr, “Operator stack is empty…\n”);
  return ‘+’;   /* 如果运算符栈为空,默认返回’+’ */
 }
    –(p_operstack->top);
   
    return temp;
}

void push_stack_oper(struct stack_oper *p_operstack, char oper)
{
 ++(p_operstack->top);
    (p_operstack -> oper)[p_operstack->top] = oper;
}

float pop_stack_data(struct stack_data *p_datastack)
{
 float temp;
 
 if (p_datastack->top >= 0)
 {
  temp = (p_datastack -> data)[p_datastack->top];
 }
 else
 {
  fprintf(stderr, “Data stack is empty…\n”);
  return 0.0;   /* 如果数据栈为空,默认返回0.0 */
 }
 –(p_datastack->top);
 
 return temp;
}

void push_stack_data(struct stack_data *p_datastack, float data)
{
 ++(p_datastack->top);
 (p_datastack -> data)[p_datastack->top] = data;
}

float cal_part(float data[], char oper[], int data_index, int oper_index)
{
 float  result = 0.0;
 int    i, j, m, n;
 
 i = data_index-1;
 j = oper_index-1;
 //result = data[i];
 
 /* debug */
 /*
 {
  int  t1;
  
  for (t1=0; t1<data_index; ++t1)
   printf(”%.2f “, data[t1]);
  printf(”\n”);
 }
 */
 
 /* 先处理’*'跟’/',因为优先级更高 */
 –i;
 for ( ; j >= 0; –j)
 {
  switch (oper[j])
  {
  case ‘*’:
   data[i+1] = data[i+1] * data[i];
   for (m = i + 1; m < data_index; ++m)   /* 左移后面那段数据 */
   {
    data[m-1] = data[m];
   }
   –data_index;
   for (n = j + 1; n < oper_index; ++n)   /* 左移后面那些操作符 */
   {
    oper[n-1] = oper[n];
   }
   –oper_index;
   break;
   
  case ‘/’:
   if (data[i] != 0.0)
   {
    data[i+1] = data[i+1] / data[i];
   }
   else
   {
    fprintf(stderr, “Devide 0…program quit!\n”);
    exit(1);
   }
   for (m = i + 1; m < data_index; ++m)   /* 左移后面那段数据 */
   {
    data[m-1] = data[m];
   }
   –data_index;
   for (n = j + 1; n < oper_index; ++n)   /* 左移后面那些操作符 */
   {
    oper[n-1] = oper[n];
   }
   –oper_index;
   break;
   
  default:
   break;
  }
  –i;
 }
 
 i = data_index-1;
 j = oper_index-1;
 
 /* 再处理’+'跟’-’ */
 result = data[i];
 –i;
 for ( ; j >= 0; –j)
 {
  switch (oper[j])
  {
  case ‘+’:
   result += data[i];
   break;
  case ‘-’:
   result -= data[i];
   break;
  default:
   break;
  }
  –i;
 }
 
 return result; 
}

float compvalue(char exp[])
{
 char   part_oper[20] = {0};  /* 存放运算符数组 */
 float  part_data[21] = {0.0};/* 存放浮点数数组 */
 char   p_data[16] = {0};     /* 存放浮点数字符串 */
 char   *p_exp = NULL;        /* 指向表达式某个字符 */
 float  data = 0.0;           /* 存放转换后的浮点数 */
 float  part_result = 0.0;    /* 存放结果值 */  
 int    sdata_index = 0;      /* 浮点数字符串指示器 */
 int    oper_index = 0;       /* 运算符数组指示器 */
 int    data_index = 0;       /* 浮点数组指示器 */
 char   temp = 0;             /* 临时存放出栈字符 */
 
 p_exp = exp;
 
    while (*p_exp != 0)
    {
     switch (*p_exp)
     {
     case ‘ ‘:   /* 如果是空格,什么都不做 */
      break;
     case ‘(’:
      push_stack_oper(&operstack, *p_exp);
      break;
      
     case ‘*’:
      push_stack_oper(&operstack, *p_exp);
      break;
      
     case ‘+’:
      push_stack_oper(&operstack, *p_exp);
      break;
      
     case ‘-’:
      push_stack_oper(&operstack, *p_exp);
      break;
      
     case ‘/’:
      push_stack_oper(&operstack, *p_exp);
      break;
      
     case ‘)’:   /* 此时计算该括号内的表达式的值 */
      part_data[data_index] = pop_stack_data(&datastack);
      ++data_index;
      //temp = pop_stack_oper(&operstack);
      while ( (temp=pop_stack_oper(&operstack)) != ‘(’)
      {
       part_oper[oper_index] = temp;
       ++oper_index;
       part_data[data_index] = pop_stack_data(&datastack);
       ++data_index;
      }
      part_result = cal_part(part_data, part_oper, data_index, oper_index);
      //printf(”part result:%.2f\n”, part_result);  /* debug */
      push_stack_data(&datastack, part_result);
      
      /* reset */
      memset(part_oper, 0, sizeof(part_oper));
      memset(part_data, 0, sizeof(part_data));
      data_index = 0;
      oper_index = 0;
      part_result = 0.0;
      
      /* debug */
      /*
      {
       int  h;
       for (h = 0; h <= datastack.top; ++h)
        printf(”%.2f “, datastack.data[h]);
       printf(”\n”);
       
       for (h = 0; h <= operstack.top; ++h)
        printf(”%c “, operstack.oper[h]);
       printf(”\n”);
      }
      */
      break;
      
     default:
      p_data[sdata_index] = *p_exp;
      
      if ( (*(p_exp+1) == ‘(’) || (*(p_exp+1) == ‘*’) || (*(p_exp+1) == ‘+’) ||
        (*(p_exp+1) == ‘-’) || (*(p_exp+1) == ‘/’) || (*(p_exp+1) == ‘)’) ||
        (*(p_exp+1) == 0) )      
         {
          p_data[sdata_index+1] = 0;
          data = atof(p_data);      /* 把字符串转换成浮点类型 */
          push_stack_data(&datastack, data);  /* 该浮点数进栈 */
          memset(p_data, 0, sizeof(p_data));  /* reset */
          sdata_index = 0;   /* reset */
         }
         else
       ++sdata_index;
      
      break;
      
     }

     ++p_exp;    /* 字符指针后移,助于遍历 */
    }
   
    /* 先判断栈是否为空 */
    if (operstack.top < 0) /* 运算符栈为空说明运算完毕,只要弹出数据栈中的数据(也就是结果) */
    {
     return pop_stack_data(&datastack);  
    }
    else   /* 计算 */
    {
     /*
     * 所有数据跟运算符出栈
     */
     part_data[data_index] = pop_stack_data(&datastack);
     ++data_index;
     
     while ( operstack.top >= 0)   /* 保证所有的运算符都出栈 */
     {
      part_oper[oper_index] = pop_stack_oper(&operstack);
      ++oper_index;
      part_data[data_index] = pop_stack_data(&datastack);
      ++data_index;
     }
     
     return cal_part(part_data, part_oper, data_index, oper_index);
    }
}

int main(void)
{
    char exp[81] = {0};
   
    memset(&operstack, 0, sizeof(operstack));
    memset(&datastack, 0, sizeof(datastack));
   
    operstack.top = -1;
    datastack.top = -1;
   
    printf(”请输入算术表达式:\n”);
    scanf(”%s”, exp);
    exp[strlen(exp)] = 0;
    printf(”%s计算结果:%.2f\n”, exp, compvalue(exp) );
   
    return 0;
}

来说两句吧

在评论中,你可以使用以下标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>