1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 #include <math.h> 6 #include <stdbool.h> 7 #include <malloc.h> 8 9 #define STACK_SIZE 100 10 #define APPEND_SIZE 10 11 12 struct SNode 13 { 14 double data; //存放操作数或者计算结果 15 char ch; //存放运算符 16 }; 17 struct Stack //顺序栈,用于计算表达式 18 { 19 struct SNode *top; 20 struct SNode *base; 21 int size; 22 }; 23 24 int InitStack(struct Stack *S); //初始化栈 25 int DestroyStack(struct Stack *S); //销毁栈 26 int ClearStack(struct Stack *S); //清空栈 27 int GetTop(struct Stack S, struct SNode *Elem); //取出栈顶结点并返回节点值 28 int Push(struct Stack *S, struct SNode Elem); //入栈 29 int Pop(struct Stack *S, struct SNode *Elem); //出栈 30 31 32 33 void OutPut(char *pFormula, double CurrentNum, int Mflg);//主循环格式输出 34 int RtOpe(char **pKey, char *pIn); //判断操作符以及计算器功能 35 double Cal(char *pFormula); //计算表达式 36 int Check(char *pFormula); //检查表达式 37 38 char Judge(struct SNode Popc, struct SNode Cr);//比较运算符优先级 39 double Operate(double Numa, char Opr, double Numb);//计算a,b经过opr运算后的结果 40 char *killzero(char *Str, double Result);//消除末尾的0 41 42 int main(void) 43 { 44 char Formula[100]={'\0'}; 45 char *pFormula=Formula; 46 char In[20]; 47 48 int M=0,Mflg=0; 49 char *Key[17]={"+","-","*","/","=","MC","MR","MS","M+","M-","CE","C","~","sqr","rec","(",")"}; 50 char **pKey=Key; 51 double CurrentNum =0; 52 bool fg=false; 53 54 OutPut(pFormula , CurrentNum, Mflg); 55 while (1) 56 { 57 scanf("%s", In); 58 if(isdigit(In[0]) != 0)//当前输入的是数字 59 { 60 CurrentNum=atof(In); 61 if(false == fg) 62 { 63 strcat(pFormula, In); 64 } 65 fg=false; 66 } 67 else //当前输入的是操作符 68 { 69 switch(RtOpe(pKey, In))//判断是什么操作符 70 { 71 case 0://"+" 写入算式 72 { 73 strcat(pFormula, In); 74 fg=false; 75 break; 76 } 77 case 1://"-" 写入算式 78 { 79 strcat(pFormula, In); 80 fg=false; 81 break; 82 } 83 case 2://"*" 写入算式 84 { 85 strcat(pFormula, In); 86 fg=false; 87 break; 88 } 89 case 3://"/" 写入算式 90 { 91 strcat(pFormula, In); 92 fg=false; 93 break; 94 } 95 case 4://"=" 计算算式的值 96 { 97 CurrentNum=Cal(pFormula); 98 fg=false; 99 break; 100 } 101 case 5://"MC" 清除存储器中的值 102 { 103 M=0; 104 Mflg=0; 105 fg=false; 106 break; 107 } 108 case 6://"MR" 显示存储器中的值 109 { 110 CurrentNum=M; 111 fg=false; 112 break; 113 } 114 case 7://"MS" 将当前的值存放到存储器中 115 { 116 M=CurrentNum; 117 Mflg=1; 118 fg=true; 119 break; 120 } 121 case 8://"M+" 将当前值和存储器中的值相加并存储 122 { 123 M+=CurrentNum; 124 fg=false; 125 break; 126 } 127 case 9://"M-" 将存储器中的值减去当前值并存储 128 { 129 M-=CurrentNum; 130 fg=false; 131 break; 132 } 133 case 10://"CE" 清除显示的数字 134 { 135 CurrentNum=0; 136 fg=false; 137 break; 138 } 139 case 11://"C" 归零,清除当前的计算 140 { 141 CurrentNum=0; 142 Formula[0]='\0'; 143 fg=false; 144 break; 145 } 146 case 12://"~"改变当前值的正负 147 { 148 CurrentNum=0-CurrentNum; 149 fg=false; 150 break; 151 } 152 case 13://"sqr"求当前值的平方根 153 { 154 if(CurrentNum >= 0) 155 { 156 CurrentNum=sqrt(CurrentNum); 157 } 158 else 159 { 160 printf("\nError Calculate !\n"); 161 } 162 fg=false; 163 break; 164 } 165 case 14://"rec"求显示数字的1/x的值 166 { 167 if(CurrentNum != 0) 168 { 169 CurrentNum=1/CurrentNum; 170 } 171 else 172 { 173 printf("\nError Calculate !\n"); 174 } 175 fg=false; 176 break; 177 } 178 case 15://"(" 写入算式 179 { 180 strcat(pFormula, In); 181 fg=false; 182 break; 183 } 184 case 16://")" 写入算式 185 { 186 strcat(pFormula, In); 187 fg=false; 188 break; 189 } 190 default:printf("\nError input !\n"); 191 fg=false; 192 break; 193 } 194 } 195 OutPut(pFormula, CurrentNum, Mflg); 196 } 197 return 0; 198 } 199 200 void OutPut(char *pFormula, double CurrentNum, int Mflg)//主循环格式输出 201 { 202 system("cls"); 203 int i=0; 204 char Str[50]; 205 char *pStr=Str; 206 double num=CurrentNum; 207 if(num >= 999999999999999) 208 { 209 num=999999999999999; 210 } 211 printf("\n"); 212 213 while (*(pFormula+i) != '\0') 214 { 215 printf("%c", *(pFormula+i)); 216 i++; 217 } 218 printf("\n"); 219 if(Mflg == 1) 220 { 221 printf("M"); 222 } 223 printf("\t%s\n", killzero(pStr, num)); 224 printf("\nMC\tMR\tMS\tM+\tM-\tCE\tC\t~\tsqr\trec\t(\t)\ninput:"); 225 226 } 227 228 int RtOpe(char **pKey, char *pIn)//判断输入的操作符或者功能 229 { 230 int i; 231 for(i=0; i<17; i++) 232 { 233 if(strcmp(pKey[i], pIn) == 0) 234 { 235 return i; 236 } 237 } 238 return -1; 239 } 240 241 242 int Check(char *pFormula)//判断表达式是否合格 243 { 244 int i=0; 245 int flag=0; 246 while(*(pFormula+i) != '\0') 247 { 248 if((*(pFormula+i) >= '0' && *(pFormula+i) <= '9') || *(pFormula+i) == '+' || *(pFormula+i) == '-' 249 || *(pFormula+i) == '*' || *(pFormula+i) == '/' || *(pFormula+i) == '(' 250 || *(pFormula+i) == ')' || *(pFormula+i) == '.') 251 { 252 if(*(pFormula+i) == '(') 253 { 254 flag++; 255 } 256 else if(*(pFormula+i) == ')') 257 { 258 flag--; 259 } 260 } 261 else 262 { 263 printf("\nError formula !\n"); 264 return 0; 265 } 266 i++; 267 } 268 if(flag != 0) 269 { 270 printf("\nthe number '(',')' is wrong !\n"); 271 return 0; 272 } 273 else 274 { 275 return 1; 276 } 277 } 278 279 int InitStack(struct Stack *S)//初始化栈 280 { 281 S->base=(struct SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); 282 if(S->base == NULL) 283 { 284 printf("\nMemory allocation failure !\n"); 285 return -1; 286 } 287 S->top=S->base; 288 S->size=STACK_SIZE; 289 return 0; 290 } 291 292 int DestroyStack(struct Stack *S)//销毁栈 293 { 294 free(S->base); 295 return 0; 296 } 297 298 int ClearStack(struct Stack *S)//清除栈 299 { 300 S->top=S->base; 301 return 0; 302 } 303 304 int GetTop(struct Stack S, struct SNode *Elem)//取出栈顶结点并返回节点值 305 { 306 if(S.top == S.base) 307 { 308 printf("Stack is empty !"); 309 return -1; 310 } 311 *Elem=*(S.top-1); 312 return 0; 313 } 314 315 int Push(struct Stack *S, struct SNode Elem)//入栈 316 { 317 if(((S->top)-(S->base)) >= S->size) 318 { 319 S->base=(struct SNode *)realloc(S->base,(S->size+APPEND_SIZE)*sizeof(struct SNode)); 320 if(S->base == NULL) 321 { 322 printf("Memory allocation failure !"); 323 return -1; 324 } 325 S->top=S->base+S->size; 326 S->size+=APPEND_SIZE; 327 } 328 *(S->top)=Elem; 329 S->top++; 330 return 0; 331 } 332 333 int Pop(struct Stack *S, struct SNode *Elem)//出栈 334 { 335 if(S->top == S->base) 336 { 337 printf("Stack is empty !"); 338 return -1; 339 } 340 *Elem=*(S->top-1); 341 S->top--; 342 return 0; 343 } 344 345 346 double Operate(double Numa, char Opr, double Numb)//计算Numa,Numb经过Opr运算后的结果 347 { 348 switch(Opr) 349 { 350 case '+': 351 return (Numa+Numb); 352 case '-': 353 return (Numa-Numb); 354 case '*': 355 return (Numa*Numb); 356 case '/': 357 { 358 if(Numb != 0) 359 { 360 return (Numa/Numb); 361 } 362 else 363 { 364 printf("\nDivide by zero !\n"); 365 } 366 } 367 default : 368 return 0; 369 } 370 } 371 372 char Judge(struct SNode Popc, struct SNode Cr)//比较操作符优先级 373 { 374 char c; 375 int i,j; 376 char Prior[7][7] = 377 { 378 {'>','>','<','<','<','>','>'}, 379 {'>','>','<','<','<','>','>'}, 380 {'>','>','>','>','<','>','>'}, 381 {'>','>','>','>','<','>','>'}, 382 {'<','<','<','<','<','=',' '}, 383 {'>','>','>','>',' ','>','>'}, 384 {'<','<','<','<','<',' ','='} 385 };// 算符间的优先关系 386 char Opt[7]={'+','-','*','/','(',')','#'}; 387 for(i=0;i<7;i++) 388 { 389 if(Popc.ch == Opt[i]) 390 break; 391 } 392 for(j=0;j<7;j++) 393 { 394 if(Cr.ch == Opt[j]) 395 break; 396 } 397 c=Prior[i][j]; 398 return c; 399 } 400 401 char *killzero(char *Str, double Result)//消除末尾的0 402 { 403 int i; 404 sprintf(Str,"%lf",Result); 405 i=strlen(Str)-1; 406 while(i && (Str[i] == '0')) 407 { 408 Str[i]='\0'; 409 i--; 410 } 411 if(Str[i] == '.') 412 Str[i]='\0'; 413 return Str; 414 } 415 416 double Cal(char *pFormula)//计算表达式 417 { 418 struct Stack optr,opnd,*Poptr,*Popnd; 419 Poptr = &optr; 420 Popnd = &opnd; 421 422 int i=0,j=0; 423 struct SNode Numa,Numb,Opr,Outopr,tem,result; 424 struct SNode *pNuma=&Numa; 425 struct SNode *pNumb=&Numb; 426 struct SNode *pOpr=&Opr; 427 428 struct SNode *pOutopr=&Outopr; 429 struct SNode *presult=&result; 430 struct SNode *ptem=&tem; 431 result.data=0; 432 433 struct SNode xTem,TemResult,Data,Crtem; 434 435 char Temp[20]={'\0'},Cntem[2]; 436 char CpFormula[102]; 437 xTem.ch='#'; 438 439 InitStack(Poptr); //运算符栈 440 Push(Poptr, xTem); 441 InitStack(Popnd); //数字栈 442 Check(pFormula); 443 444 while(*(pFormula+j) != '\0') 445 { 446 CpFormula[j]=*(pFormula+j); 447 j++; 448 } 449 CpFormula[j]='\0'; 450 strcat(CpFormula, "#"); 451 printf("\n%s\n", CpFormula); 452 453 454 while(CpFormula[i] != '\0') 455 { 456 if(((CpFormula[i] >= '0') && (CpFormula[i] <= '9'))||(CpFormula[i] == '.'))//当前为数字,或者. 457 { 458 Cntem[0]=CpFormula[i]; 459 Cntem[1]='\0'; 460 strcat(Temp, Cntem); 461 if((CpFormula[i+1] == '+') || (CpFormula[i+1] == '-')|| (CpFormula[i+1] == '*')|| (CpFormula[i+1] == '/') 462 || (CpFormula[i+1] == '(')|| (CpFormula[i+1] == ')') || (CpFormula[i+1] == '#')) 463 { 464 Data.data=(double)atof(Temp); 465 Push(Popnd, Data); 466 //printf("\nPush opnd\n"); 467 strcpy(Temp, "\0"); 468 } 469 i++; 470 } 471 else //当前为操作符 472 { 473 Crtem.ch=CpFormula[i]; 474 GetTop(optr, ptem); 475 switch (Judge(tem, Crtem)) 476 { 477 case '<': // 栈顶元素优先权低 478 { 479 Push(Poptr, Crtem); 480 //printf("\nPush optr\n"); 481 i++; 482 break; 483 } 484 case '=': // 脱括号并接收下一字符 485 { 486 Pop(Poptr, pOutopr); 487 //printf("\nPop optr\n"); 488 i++; 489 break; 490 } 491 case '>': // 退栈并将运算结果入栈 492 { 493 Pop(Poptr, pOpr); 494 Pop(Popnd, pNumb); 495 Pop(Popnd, pNuma); 496 TemResult.data=Operate(Numa.data, Opr.ch, Numb.data); 497 //printf("\n> %.4f\n",y.data); 498 499 Push(Popnd, TemResult); 500 break; 501 } 502 default: 503 { 504 printf("\nError !\n"); 505 break; 506 } 507 } 508 } 509 } 510 511 Pop(Popnd, presult); 512 DestroyStack(Poptr); 513 DestroyStack(Popnd); 514 //printf("\n%.4f\n",result.data);*/ 515 return result.data; 516 }