基于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 }

 

posted @ 2018-03-05 11:38  漆天初晓  阅读(445)  评论(0编辑  收藏  举报