捌玖网络工作室's Archiver

zw2004 发表于 2008-1-21 17:17

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
!aev(qo$K 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
,p)Q`bw#_ /**************表达式计算器************/
g kI-P"PF uY Lx #include <stdio.h> e+J3uhw#U:^
#include <stdlib.h>
$QY|II:} #include <string.h>4Ht"Yo i0h;uf
#include <conio.h> Kt!a:]z\9{
#include <malloc.h>G9yn)Mb\ _y0MA
RMn"t x6KjB
#define STACK_SIZE 100
g`1_MH #define APPEND_SIZE 10
{*d2nxtd7B Du/n!K L@A2xj-a
struct SNode{F7AL,U(J}2@
    float data; /*存放操作数或者计算结果*/'Cxs/HaH"O
    char ch; /*存放运算符*/c}9E2T;TL
}; ~lC.^ p B.I
yniV9{'J
struct Stack{W*L,?8n p [
    SNode *top;
(T dOe&fs     SNode *base;
b&Hg3bf!B{t,}u5j     int size;tfcy.i
};
fE7S@h_$i
U*zaFL/W^"Bi /*栈操作函数*/
4w]#Xa~q int InitStack(Stack &S); /*创建栈*/
Z(O| r,g int DestroyStack(Stack &S); /*销毁栈*/#Q%e_f1OAg
int ClearStack(Stack &S); /*清空栈*/
A'c [6z BR int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/2{I&tU h Q j/?8\
int Push(Stack &S,SNode e); /*将结点e压入栈*/uKm%[#R!n
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
VN6fSh4hB$k
U2}S$O8W_2a /*表达式计算器相关函数*/
!p F'H?dYb char get_precede(char s,char c); /*判断运算符s和c的优先级*/
Yr6mh;B]'K int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/!AI&Gk,E Y2v
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+lk Un/] K float compute(); /*表达式结算器主函数*/
!h9i2Y@*S#O;T!e char *killzero(float result); /*去掉结果后面的0*/
$G3RWdOu8p ?|t2|%u8i I
int InitStack(Stack &S)
$QJ?/yXA"Q {
-GVz[p     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
_F4[C6K9r ZA     if(S.base==NULL)?!eBP(r
    {
N$I+{ lQ$Py\         printf("动态分配内存失败!");
*TC[0WE+~         return -1;8fu:pg5XU;^
    }3G1D,w,e Lt+Bu%C[
    S.top=S.base;t|cwh
    S.size=STACK_SIZE;I,Qfv#J C;S#`8j
    return 0;
}@)eF J*l:R })]z e4Ja$`
n;e q:q1RJEd&P C#V
int DestroyStack(Stack &S)
6T-KrrJ!C`0t'Y {
1F%a-d.\~4g fyQ     free(S.base);s,b+tA ~'k,?
    return 0;\%\H8p:KY"WE&b
}/XQ/G(_8AR+h t

_T0C-g.M;HN a int ClearStack(Stack &S)
&cwe/rd g {+l6nJz \X:m
    S.top=S.base; s s{E8W"?Mu"EE O
    return 0;Z5jTYWbB |
}
I:Z1wj^?+Asp
}1POn a~E Z int GetTop(Stack S,SNode &e)
Y6g,mM+w$lxC$I5? {
} Br.V0F`     if(S.top==S.base);w`)yC+Lg}V
    {g^C ab ]a3\
        printf("栈以为空!");
z[ CYySb         return -1;z5d$Dk1PG*mvO
    }rF^tWJ2~m;E7pr'EV
    e=*(S.top-1);
vYq#R#yyv3T)_RZ0o     return 0;
,z R^8_r(n~E }/n+M_2_0p"Ei
.[ Jct@Lf-b*O
int Push(Stack &S,SNode e)]\E} ?&m*j n:^
{
R"J.Xu0yjD     if(S.top-S.base>=S.size)E'I T(`7v|vW
    {
!yn3_j P[.nO[         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
8`-k~Kcs[         if(S.base==NULL)!R2N7@$h,N-_4z:Wl
        {^.cZdiz
            printf("动态分配内存失败!");[hb#D5_kA
            return -1;2I.L0X2[ t0k;Mr
        }
kG:U-qk9Jb$K         S.top=S.base+S.size;Q \+l0K F+z;|
        S.size+=APPEND_SIZE; G-A]]*B7CN"Z3`
    }
F{!R!I S2Z&y \     *S.top=e;3|]Ufoc)I
    S.top++;
'H,L5Rb)~+L,]'T     return 0;
uyGMqN4U }y?p+O`4f!f
G,jR2p L,I*nk?,cR
int Pop(Stack &S,SNode &e)
Q%i-i/L9p4pN {
(b["r%w(m[yY8GF"u$U     if(S.top==S.base)
f YE`.S5fs     {
9G}`(~n l(L,Pu:J:L         printf("栈为空!");
[u*y\-bS         return -1;*X-Un5n;wSUH
    }
W"_|6e,V HJh     e=*(S.top-1);
H\s)K.m&U9j7Ar `     S.top--;
[V,^k9i;Ly.nH     return 0;IY_U7O(n
}
m`|9^?'B"u D5Z8eX:l Z:Q RPy?U
char get_precede(char s,char c)o5W|`U
{L4Vw.B Y~"K?'Wi
    switch(s)
*p)bF"i:Y2[8p ^9X(p     {
\k6P TLW;N6rUM         case '+':                 
9Zi dv9z e k.Zxb*Nj"h         case '-':
7e;]0T7l)~;`a              if(c=='+'||c=='-')fBS)L~k!Jv e_
                 return '>';t]V7u yk5E"~
             else if(c=='*'||c=='/')+t4FP-N%H+_1g0}bc$lj
                 return '<';]$nj3iN
             else if(c=='(')3T_1n\V K\ B(S
                 return '<';
I#v]F[@4q              else if(c==')')
[ a)]7I?^tL7uj                  return '>';VvqO P3lF"ST)}K@4v
             else c.AY r J"stTP
                 return '>';JTP NN}9R(c,j,X W
        case '*':
_?R5Dc,q8e e!A2g         case '/':zKF%th~D#s
             if(c=='+'||c=='-')
L5tTdg!B&J                  return '>';
;[|*}'C7Z:[ yW\              else if(c=='*'||c=='/')
YX aQt+{f                  return '>';jY@N~&z
             else if(c=='(')
"kdM`E+`                  return '<';
%Ee nEy?LlK$kl              else if(c==')')@;P9\dTSP
                 return '>';;^@zw$i.^[1M?[
             else
ulZ;gP t5V }R                  return '>';9jcrC#\s9c
        case '(':^5{]6Fp:rn [I
             if(c=='+'||c=='-')
O,a#M+wh7\Z                  return '<';
EGf6hqo e*sI"v4]              else if(c=='*'||c=='/')
M`(C?9w#t;K4S                  return '<';4NE:C5Z"P$z
             else if(c=='(')
"y*}[/N},p e                  return '<';SEh.yc+byb~7F]
             else if(c==')')
/x3Es/nn1?P                  return '='; {2m7vd4O
             else
.T0S-Tq:CCF7[+D                  return 'E';
E)fcu%i;w         case ')':
4iM n f7ddD.b O              if(c=='+'||c=='-')k&M0Q6d#w.cmbwY
                 return '>';(V!dm:?v,Y~/Ure
             else if(c=='*'||c=='/')eLsVc$v J
                 return '>';
(mx+c:q AT E3F              else if(c=='(')b;V{_j
                 return 'E';9N q P!{.E;q)k
             else if(c==')')S&`y7Ph%w7Ql'a
                 return '>';
T P;o bVh/Wx_5N+@              else9] a]bs ]
                 return '>'; {ze*QX1A"J']
        case '#':
:e6a`Ai Si:zC['T              if(c=='+'||c=='-')
)o3? l6E6P I_                  return '<';RqN:VZG
             else if(c=='*'||c=='/')`]8g4r/o!\
                 return '<';w6j}ho/Jp-{;L
             else if(c=='(')
^)bN[3{ t i(}]                  return '<';
M\2w4uG              else if(c==')')
j+e'ik+g-z&Uc                  return 'E';N }Hk*Y v0]
             else*K&c!r*SAH R9d;B
                 return '=';_Fj:vN
        default:U,a3iow#qU)fJ
             break;
tD0dS(r.p x-UaD`     }
_;fn:vb     return 0;   
_1@/K)}1OQ)mt-Y$G }
zvG!b] f
+y@(t"qJ:G int isOpr(char c)0Y7z8wz[Vp3W\"[,]
{
(m9q"e9z9f(f     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
.q)h*vnM5~y"^         return 0;IPRr*ey*Il
    else
H;qB _4l         return 1;
#~9tN4R,v:t }
D;?_c0Ce ,I8F8w_uO Af-R
float operate(float x, char opr, float y)
~#E%d[R/T0yx {
"t9x(m3@Px~     float result; ow$i4\b G!W
    switch (opr)
"u%{'DU)WO K     {.G&u ^0ztm8Xq
        case '+': Lr5t7S _)Me
             result = x + y;};c/v+eBy d
             break;+I,}q%Mv6KXA
        case '-':
;Ks5A3qKP tM*f              result = x - y;m$UW~-S+qB:LO.s
             break;*O hj5y Q-C
        case '*':
&q Zip)}k              result = x * y;
1p)k B9]k7d{3pK              break;
Sq.VM-@         case '/': ,s(|!Mq:s? p
             if (y == 0)
ct2H,J*K S              {
W8Ru(RQ                 printf("Divided by zero!\n");
2x(n Ys ~,h                 return 0;
2h1pI4y Zal2Q0ih              }
J;U7d@,T8G/dv.Z              elseWBc,\9C vJ3J\
             {
7|Rw$J-w)X3v                  result = x / y;"d sC#g bZ/HLX6n+A[ F
                 break;
;jn'o'}U zv              }4|4^+x$[B#\AB
       default:
Mmk p~!Y v,eS              printf("Bad Input.\n"); r6w+c0l^%~;bz
             return 0;
fjr+PZw5ce     }8\:@Y(B&tLe7k1a
    return result;
Ts(I6_0\~ }   
Jz5eY8n k]_k-a aM1w Dco
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1}n/G x6|HG
{
)Q/NxB"xJ_,M q     Stack optr,opnd;u(JAZK Uo[
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;'C/@,~5])XZ
    char c;
K+~v p)F     char buf[16];
(iz;i:pV6uQ     int i=0;-w?yqH| ]t9g.g
    'tp1W&hf [FH1a
    InitStack(optr); /*用于寄存运算符*/
1c B z's%]XnJy     InitStack(opnd); /*用于寄存操作数和计算结果*/
/G-p(C"J R W\     memset(buf,0,sizeof(buf));
h!y0d,vU    
4F5y.^2fj S     printf("Enter your expression:");#SR(p5k\8Ud)C
        v"c"{ Dq@ |h;]$T+D
    opr_in.ch='#';
p5x+U%@Cr}     Push(optr,opr_in); /*'#'入栈*/ |(m}BZ$|
    GetTop(optr,opr_top);
$mlfpQ"H     c=getchar();
XE Msy;|w/X7J]0A,w)k     while(c!='='||opr_top.ch!='#')
7? M]gSWa \O     {5K8UQey$ch `\
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/,O?*u f1Q)BHn~ \,?
        {
Z1LKv8R']%f             buf[i]=c;'Ghtp8{dT
            i++;4G&Fx_p&~d
            c=getchar();pIW@OJX
        }`U$Bf;F2V
        else /*是运算符*/
h]*zG9{o5Na8^-B0l         {
#T6nL O u.i             buf[i]='\0';
oHM~i/nEI:W             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
@(y4q5ac8eD             {c8|3eK{6F
                 opn_in.data=(float)atof(buf);
.D"SI,b-c,Y g}e                  Push(opnd,opn_in);
2j ~ }:S^r5?l#p+`y                  printf("opnd入栈:[%f]\n",opn_in.data);O]*K \2hJ
                 i=0;7^v]%nN2ac1c?&Q
                 memset(buf,0,sizeof(buf));c*kevJ
            }
DGe(L ^L5aBH+]             opr_in.ch=c;ZOHV} R
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Q9Ro'i-P%N]Ob'[F,L"~
            {4miyo/M_8}(}-g w(c
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
:f)q/V4r9im,QL9F,R                      Push(optr,opr_in);H!z?J4w-J^6xvQ
                     printf("optr入栈:[%c]\n",opr_in.ch);%Q2h3PRC
                     c=getchar();
$b,AVgGu9B                      break;
2?kYO"IS|M                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/a&Y8?9ztsm
                     Pop(optr,e);(Da9i!qkU
                     printf("optr出栈:去掉括号\n");
3`:B'W9R`                      c=getchar();5Mi'D6mif,vD*iH
                     break;
N$av)ERV C                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
i4_O9X*~"Mt?*J                      Pop(optr,opr_t);:c/E#^3L+n\l
                     printf("optr出栈:[%c]\n",opr_t.ch); B E a/p z`
                     if(Pop(opnd,b)<0)#Bk(U8XD \1DF
                     {Qgw D#nKm7~ dxm
                         printf("Bad Input!\n");
3qWE%o `T&U kO                          fflush(stdin);2o"c/[6kf ZJVb
                         return -1;
5N~t?F                      }
"BI2?x]!P                      printf("opnd出栈:[%f]\n",b.data);
| G#B7l3X)Z\                      if(Pop(opnd,a)<0)
uxh4L*` SG?L8f                      {/UKhm'J!ZG
                         printf("Bad Input!\n");+_qXE9a)R
                         fflush(stdin);
:n[V ii&W                          return -1;};yytT?#c
                     }
l:w{ T$UT                      printf("opnd出栈:[%f]\n",a.data);
G&T?Ou                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
6k(D(xVH1|p6RR]Y*\                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
3^4jhd iL+N                      printf("结果入栈:[%f]\n",opn_tmp.data);
~l Him];B%t O                      break;LC I"YcC&]-}"@K
            }
1Fw%nig YUV7@ _#o         }:]GiE4z2c"bo;f
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                t9J]%J$E AP
    }h:G1l1Ni
    GetTop(opnd,opn_tmp);
kI a9m/a {.}8P9d:g     DestroyStack(optr);:QV Q4u;k!^
    DestroyStack(opnd);V8F ~2{H&D
    return opn_tmp.data;7PQ'W?vDee9S,M*O
}
W!o/]h(lv)I P"]Y.TCP4}9j
char *killzero(char *res,float result)Tz(tb6kyR#\
{1P c;i m9j J
    int i;
'xOX4Qj#hxG,b 3`3cv"aUngw GL
    sprintf(res,"%f",result);
ld0P2[;fi8^z'I _     i=(int)strlen(res)-1;
~G_ ` ed     while(i&&res[i]=='0')
t@|0oJ)^     {
{ | u r,xk@2BE         res[i]='\0';\P5Y5GGF`
        i--;[P6R,oP&^0rR
    }
6p~ d]*q^v-~'}V     if(res[i]=='.')
C\7J1}8{yw9Jc         res[i]='\0';
7f!BHf$Y8y     return res;{an4`QV [I
}
} eQu1owFi u7O5s&jo:o
int main()
rC:q:l |ul"Q h6pV {0zD&? \0PU8Wm
    char ch;Eb:c&\]9D
    char res[64];
rp-g};i2\-s'JO&D     float result;#g8mIw4q4K;T\
    while(1)%}:`XX~ Pz'WZ
    {]1u*Y2jO^?+X
        result=compute();X6xM(u3Q"P;R+O`P
        printf("\nThe result is:%s\n",killzero(res,result));
|~:a h5XA"S         printf("Do you want to continue(y/n)?:") ;
w+asDP*Jx9D?         ch=getch();?l z HJJO
        putchar(ch);&zLO MpE!H
        if(ch=='n'||ch=='N')
!TGK5t tJ1C_'T             break;
^Z\B)]QYe         elseG^e,|#z ?Ggt
            system("cls");'kLJ `&U5e
    }
;n(s D+ceV\     return 0;sCn\T+zp'i)y
}[/i][/i][/i][/i][/i][/i]W$t&y&_;|
0EO tPp"~C GZ |
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

页: [1]
【捌玖网络】已经运行:


Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.