• 基于c的简易计算器一


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 #include <malloc.h>
      6 
      7 #define STACK_SIZE 100
      8 #define APPEND_SIZE 10
      9 
     10 struct SNode{
     11     float data; /*存放操作数或者计算结果*/
     12     char ch; /*存放运算符*/
     13 };
     14 
     15 struct Stack{
     16     SNode *top;
     17     SNode *base;
     18     int size;
     19 };
     20 
     21 /*栈操作函数*/
     22 int InitStack(Stack &S); /*创建栈*/
     23 int DestroyStack(Stack &S); /*销毁栈*/
     24 int ClearStack(Stack &S); /*清空栈*/
     25 int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
     26 int Push(Stack &S,SNode e); /*将结点e压入栈*/
     27 int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
     28 
     29 /*表达式计算器相关函数*/
     30 char get_precede(char s,char c); /*判断运算符s和c的优先级*/
     31 int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
     32 float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
     33 float compute(); /*表达式结算器主函数*/
     34 char *killzero(float result); /*去掉结果后面的0*/
     35 
     36 int InitStack(Stack &S)
     37 {
     38     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
     39     if(S.base==NULL)
     40     {
     41         printf("动态分配内存失败!");
     42         return -1;
     43     }
     44     S.top=S.base;
     45     S.size=STACK_SIZE;
     46     return 0;
     47 }
     48 
     49 int DestroyStack(Stack &S)
     50 {
     51     free(S.base);
     52     return 0;
     53 }
     54 
     55 int ClearStack(Stack &S)
     56 {
     57     S.top=S.base;
     58     return 0;
     59 }
     60 
     61 int GetTop(Stack S,SNode &e)
     62 {
     63     if(S.top==S.base)
     64     {
     65         printf("栈以为空!");
     66         return -1;
     67     }
     68     e=*(S.top-1);
     69     return 0;
     70 }
     71 
     72 int Push(Stack &S,SNode e)
     73 {
     74     if(S.top-S.base>=S.size)
     75     {
     76         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
     77         if(S.base==NULL)
     78         {
     79             printf("动态分配内存失败!");
     80             return -1;
     81         }
     82         S.top=S.base+S.size;
     83         S.size+=APPEND_SIZE;
     84     }
     85     *S.top=e;
     86     S.top++;
     87     return 0;
     88 }
     89 
     90 int Pop(Stack &S,SNode &e)
     91 {
     92     if(S.top==S.base)
     93     {
     94         printf("栈为空!");
     95         return -1;
     96     }
     97     e=*(S.top-1);
     98     S.top--;
     99     return 0;
    100 }
    101 
    102 char get_precede(char s,char c)
    103 {
    104     switch(s)
    105     {
    106         case '+':
    107         case '-':
    108              if(c=='+'||c=='-')
    109                  return '>';
    110              else if(c=='*'||c=='/')
    111                  return '<';
    112              else if(c=='(')
    113                  return '<';
    114              else if(c==')')
    115                  return '>';
    116              else
    117                  return '>';
    118         case '*':
    119         case '/':
    120              if(c=='+'||c=='-')
    121                  return '>';
    122              else if(c=='*'||c=='/')
    123                  return '>';
    124              else if(c=='(')
    125                  return '<';
    126              else if(c==')')
    127                  return '>';
    128              else
    129                  return '>';
    130         case '(':
    131              if(c=='+'||c=='-')
    132                  return '<';
    133              else if(c=='*'||c=='/')
    134                  return '<';
    135              else if(c=='(')
    136                  return '<';
    137              else if(c==')')
    138                  return '=';
    139              else
    140                  return 'E';
    141         case ')':
    142              if(c=='+'||c=='-')
    143                  return '>';
    144              else if(c=='*'||c=='/')
    145                  return '>';
    146              else if(c=='(')
    147                  return 'E';
    148              else if(c==')')
    149                  return '>';
    150              else
    151                  return '>';
    152         case '#':
    153              if(c=='+'||c=='-')
    154                  return '<';
    155              else if(c=='*'||c=='/')
    156                  return '<';
    157              else if(c=='(')
    158                  return '<';
    159              else if(c==')')
    160                  return 'E';
    161              else
    162                  return '=';
    163         default:
    164              break;
    165     }
    166     return 0;
    167 }
    168 
    169 int isOpr(char c)
    170 {
    171     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
    172         return 0;
    173     else
    174         return 1;
    175 }
    176 
    177 float operate(float x, char opr, float y)
    178 {
    179     float result;
    180     switch (opr)
    181     {
    182         case '+':
    183              result = x + y;
    184              break;
    185         case '-':
    186              result = x - y;
    187              break;
    188         case '*':
    189              result = x * y;
    190              break;
    191         case '/':
    192              if (y == 0)
    193              {
    194                 printf("Divided by zero!\n");
    195                 return 0;
    196              }
    197              else
    198              {
    199                  result = x / y;
    200                  break;
    201              }
    202        default:
    203              printf("Bad Input.\n");
    204              return 0;
    205     }
    206     return result;
    207 }
    208 
    209 float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
    210 {
    211     Stack optr,opnd;
    212     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
    213     char c;
    214     char buf[16];
    215     int i=0;
    216 
    217     InitStack(optr); /*用于寄存运算符*/
    218     InitStack(opnd); /*用于寄存操作数和计算结果*/
    219     memset(buf,0,sizeof(buf));
    220 
    221     printf("Enter your expression:");
    222 
    223     opr_in.ch='#';
    224     Push(optr,opr_in); /*'#'入栈*/
    225     GetTop(optr,opr_top);
    226     c=getchar();
    227     while(c!='='||opr_top.ch!='#')
    228     {
    229         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
    230         {
    231             buf[i]=c;
    232             i++;
    233             c=getchar();
    234         }
    235         else /*是运算符*/
    236         {
    237             buf[i]='\0';
    238             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
    239             {
    240                  opn_in.data=(float)atof(buf);
    241                  Push(opnd,opn_in);
    242                  printf("opnd入栈:[%f]\n",opn_in.data);
    243                  i=0;
    244                  memset(buf,0,sizeof(buf));
    245             }
    246             opr_in.ch=c;
    247             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
    248             {
    249                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
    250                      Push(optr,opr_in);
    251                      printf("optr入栈:[%c]\n",opr_in.ch);
    252                      c=getchar();
    253                      break;
    254                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
    255                      Pop(optr,e);
    256                      printf("optr出栈:去掉括号\n");
    257                      c=getchar();
    258                      break;
    259                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
    260                      Pop(optr,opr_t);
    261                      printf("optr出栈:[%c]\n",opr_t.ch);
    262                      if(Pop(opnd,b)<0)
    263                      {
    264                          printf("Bad Input!\n");
    265                          fflush(stdin);
    266                          return -1;
    267                      }
    268                      printf("opnd出栈:[%f]\n",b.data);
    269                      if(Pop(opnd,a)<0)
    270                      {
    271                          printf("Bad Input!\n");
    272                          fflush(stdin);
    273                          return -1;
    274                      }
    275                      printf("opnd出栈:[%f]\n",a.data);
    276                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
    277                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
    278                      printf("结果入栈:[%f]\n",opn_tmp.data);
    279                      break;
    280             }
    281         }
    282         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
    283     }
    284     GetTop(opnd,opn_tmp);
    285     DestroyStack(optr);
    286     DestroyStack(opnd);
    287     return opn_tmp.data;
    288 }
    289 
    290 char *killzero(char *res,float result)
    291 {
    292     int i;
    293 
    294     sprintf(res,"%f",result);
    295     i=(int)strlen(res)-1;
    296     while(i&&res[i]=='0')
    297     {
    298         res[i]='\0';
    299         i--;
    300     }
    301     if(res[i]=='.')
    302         res[i]='\0';
    303     return res;
    304 }
    305 
    306 int main()
    307 {
    308     char ch;
    309     char res[64];
    310     float result;
    311     while(1)
    312     {
    313         result=compute();
    314         printf("\nThe result is:%s\n",killzero(res,result));
    315         printf("Do you want to continue(y/n)?:") ;
    316         getchar();
    317         scanf("%c",&ch);
    318         putchar(ch);
    319         if(ch=='n'||ch=='N')
    320             break;
    321         else
    322             system("cls");
    323     }
    324     return 0;
    325 }
  • 相关阅读:
    开源库dlib的安装与编译-CMake
    Python的zip函数
    matlab读写视频VideoReader/VideoWriter
    批量分割视频opencv
    批量重命名文件
    OpenCV代码提取:遍历指定目录下指定文件的实现
    第48课 函数设计原则(完)
    在Qt中如何使用QtDesigner创建的UI文件(一) (转)
    qt ui程序使用Linux的文件操作open、close (转)
    进程间通信IPC之--无名管道(pipe)和有名管道(fifo)(转)
  • 原文地址:https://www.cnblogs.com/tyche116/p/8508171.html
Copyright © 2020-2023  润新知