捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
!_q!f i ig 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=~'bE)s#q~i+b
/**************表达式计算器************/$U0I1L8})p#pH
#include <stdio.h>
'F:Qd A)U7{$i2]/Z #include <stdlib.h>
9t f ]eIG"l'Zj g #include <string.h>
:Ee c+]"`h\T #include <conio.h>
\ NFU+K0B\ #include <malloc.h> [j2b3[%d"YDI
eICAV]3D`N
#define STACK_SIZE 100
+K;G#sJ mjh Lm]+Qj #define APPEND_SIZE 10_#v,kM];`)l
!v2g|9X#`oS
struct SNode{
v1RB/Bu Z1qK&g     float data; /*存放操作数或者计算结果*/w}*r$GXd4t
    char ch; /*存放运算符*/
%BZC)q?JW/_Y };2s?e6Y8q`6M(R`

~_ZJ:[ struct Stack{
-]Jh0M[Mkm }     SNode *top;|Fb&OYV4s m/r
    SNode *base;
vAy8zN     int size;If~1s!TQ&QA6J,M
};'p@ j;R+BY-Ic

k"y6D%~\@ /*栈操作函数*/y$| b$Al D U$~]8K
int InitStack(Stack &S); /*创建栈*/t bM'Lrb ^ke8v*Ny
int DestroyStack(Stack &S); /*销毁栈*/QI8lZ,Hm*a,b5{
int ClearStack(Stack &S); /*清空栈*/.?U&oOd
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
Y&kMx;uU}\ int Push(Stack &S,SNode e); /*将结点e压入栈*/#e.T9M ES9Tg9g4P!n&a p
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/~tk2O;o5k9B^\A's

u(KK#ZE3RpZ(u /*表达式计算器相关函数*/
%@(U,zD j6@ char get_precede(char s,char c); /*判断运算符s和c的优先级*/)Ssq(B7sjp+Q*rZC
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/iC|p bG
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
%z6px-p ih6i LG float compute(); /*表达式结算器主函数*/
/c&\ e dT(h char *killzero(float result); /*去掉结果后面的0*/
g,ct:[)k
#sTp8n6X,w int InitStack(Stack &S)&eQd4J-Yr'[
{_#T?;p9`3Q)uq4v
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
6T,F~#]-u     if(S.base==NULL)
L$g4l-o_`q     {
JP2a.w@,t vg*@U         printf("动态分配内存失败!");d~dV^m
        return -1;v)kw&L MvE%[a
    }j8\5_ M {oL
    S.top=S.base;c6ri7SC.[J
    S.size=STACK_SIZE;
je"dE LIX     return 0;
gb w*q _l+G!m-w }
? @-m(Y,t@$PY I nN2^ q8ug:L4g\(K R
int DestroyStack(Stack &S)
s I m'w$o G%ey {I0Js#];_C V
    free(S.base);'[4~oZB]D
    return 0;
0R?3l L zG5W Z$C }
8[*` I`h*q
#^-pyZr6z int ClearStack(Stack &S)
t;tch ls {t(|N6K#E ^r_A
    S.top=S.base;
9HY,W~8n:p     return 0;
v~Kqn!I }U y#S!eXP7d5g

1U,b:~W-z"FC int GetTop(Stack S,SNode &e)3O&@XgD({o'{6|h
{
Iv/o7^ mb2y~     if(S.top==S.base)
Dr@nZ7h$a     {
@.i!@BH0s{,Bp         printf("栈以为空!");
` m2U"_7c9{5W         return -1; MhUk,Xg
    }
F;R!Z D`E     e=*(S.top-1);
(k Q0[ hK     return 0;
*DMS ur }
*B/d;i#J@CU
-qnZ5F!U*hyA0R int Push(Stack &S,SNode e)uffM8Q4_bM-m
{5e;SmcsU
    if(S.top-S.base>=S.size)
bf"|p k| A     {jz @ ST7^-N'M
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));#k1YPd_&mU(e&J
        if(S.base==NULL)*~B-^ Sr3n2Cp
        {
nk EvB"I O             printf("动态分配内存失败!");
M U:L,{-bs(\M             return -1;(zCw!zE\#Q%?^F
        }
|@0yO+}         S.top=S.base+S.size;0fx `oG
        S.size+=APPEND_SIZE; |X?q;q(@
    }w9V;{0_@/Zk
    *S.top=e;
a:?4o~ b)`#y9Ll     S.top++;
,[Q}9h pth     return 0;
X!gKf(\\g5`S }6`EJGN)y*V&rn

M qF+DYC9B int Pop(Stack &S,SNode &e)
)Ru7\ N.Um1e'X {
i7e gX9xZrg(E? K     if(S.top==S.base)(Z(n Y[y#T
    {
/T#rt|soX1y         printf("栈为空!");s4u;A v_4]
        return -1;
*J|1zMv7CbX8j$}     } t jj"~:iWg1j
    e=*(S.top-1);
7P/[s_ K%O!MmS     S.top--;
{6|,Ou0O;H.Dn#eYi     return 0;R ^"S2X l
}_ZQ+O"VjuY X+~
q4].Y!}K Ab_)M
char get_precede(char s,char c)
} | iS,?Q4m?7E {
B*F _B4BD&|V{ |     switch(s)
.pO/S,LK%w     {
b V9|%? k(x8ja.yw         case '+':                 oTbm-~,{"p
        case '-':
\R'?6P+jT1vZ^              if(c=='+'||c=='-')
#}LhG3p ?*T7s                  return '>';"SL`j)[5?D k/J\
             else if(c=='*'||c=='/')
9J Bd#V5Rx4f                  return '<';B6aDP-I!b5Q/I2I
             else if(c=='(')[mi#NB@R-O
                 return '<';8R8@"?xi@.~q.j \4L
             else if(c==')')
#nV)_iy+c5CC                  return '>';"c9cT%]*L,M(T
             else 1y)` q vXQ.~
                 return '>';/E;K-A ~R
        case '*':
r(YZ/T s         case '/':#uOH7P(b
             if(c=='+'||c=='-')8?z#L S `y~*sgp:v
                 return '>';OXL{.e
             else if(c=='*'||c=='/')8g7p*cmab
                 return '>';
YXO"?m              else if(c=='(')#w,j rKvM
                 return '<';
F.B5X ]7y              else if(c==')')I,L6p ]5S+L"R
                 return '>';PO&rY And
             else
jE6AZ+Mu9B7x^                  return '>';J9}@?zo iw;cg
        case '(':
1CZ]R wb V+zk              if(c=='+'||c=='-')&]'tZ*m.^T`:VV
                 return '<';
^9[1Izh%EW              else if(c=='*'||c=='/') S*y7I\;hXpD
                 return '<';jjP `Nvjv
             else if(c=='(')
}5_ e O3f%|G-D3aZ                  return '<';
Z4O~2g AL              else if(c==')')
Zqm*{|,f:o%ia5B                  return '=';
0X)] f {~RtK              else{w'HM;B }
                 return 'E';
Ra9H$HFZ [N.A         case ')':
&Tsm[*A]              if(c=='+'||c=='-')4@ aH3DLV.E|0s
                 return '>';
"I7gbG h              else if(c=='*'||c=='/')
B3K~ `UP ~                  return '>';.^!U.oK,q%@3mc
             else if(c=='(')/GG#`-~zW e+U
                 return 'E';f1s K4LW"p@
             else if(c==')')
g'hg`Y~-WRJ                  return '>';Z a)}o N~N0b-_
             else
:?;d(L#t9P M3~                  return '>';
Kw+i3B5x5h'uI0_ m         case '#':Y9K/nH%DX1b&A:DM8o
             if(c=='+'||c=='-');w9BX C E5y;{?(v
                 return '<';
iOZ8JFx0PM3m              else if(c=='*'||c=='/')8SJ aJ]
                 return '<';
`^ W8R~ n              else if(c=='(')
{*vW"b:n|8x                  return '<';!s,M Pa8D:E
             else if(c==')')] ?*Y-R3De HHt&T/{
                 return 'E';
$l]2f2Z {R              elsee2X ?&m2Pgz
                 return '=';
.w oj*XM({ ^,_5q*Iu         default:
\3[ J EgS z'~#i              break;#x},w;Z/va_ n
    }
G]8r(g.b-Jn.} T#FkU     return 0;    [$Y&@|5z
}
Z*_)M!SlH 7b|~%\0`7^
int isOpr(char c)
i/W%_k;x,Hf {
5Gc"`(Y3j#F     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')i&\a0r b&ZoYS*K;e6a
        return 0;].w:h#J]+p|2cje
    else
yw+|M$KS?h j$l3[         return 1;1Fnd$_3In*d
}T(]m(Z0L

ZV@'M:z&y?j float operate(float x, char opr, float y)7N7|9y8F+@N!Eb
{MV'im~ tz? {Yf
    float result;
:u[uV1ai,BdB d     switch (opr)9CTU6e+|%H @e`e6c
    {6W{"klU0E8z
        case '+': N:K V k yG,Y"aW7m
             result = x + y;2rz!o2F3}dd9L ~
             break;%p2aNK3Y Ih+BL
        case '-':
!u'o3ZJz4I1w8L              result = x - y;:a%s.u5u7k0iC)d9e
             break;
np-w0Z)Y/Q'?ULg         case '*': FR2t/G+T$U,H(`D2V
             result = x * y;GNUZ_
             break;
(G'|Q[!d1up*?R         case '/':
4D,B cQ0@)Fln cv              if (y == 0)
!inUly?              {
,M2|2zog+m"x                 printf("Divided by zero!\n");
\-z%OZ d                 return 0; W u8@)b\}*C$J
             }x"}C|S
             else
p/R6mP^6e8W              {
f gb|D                  result = x / y;
kP'b"Ps                  break;$e{!Hkzr
             }vm%R f0w:q?
       default:
4f a0R(G2c9D~)FuEy6k#|              printf("Bad Input.\n");
uV&Vt wu~e              return 0;
M2b*M1~y-\     }%}O7f~1CN5Gc
    return result;
{vd"e0K!P }    $e$Q1N#J&k;Xv
/R%vy \Qh%X;M
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/G laI5mxOa
{ b3@3jlZ)k$~
    Stack optr,opnd;T*FR ibWQ*hzw
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
|CRp`NbH X8h     char c;9Q5_:a`W Bv)~
    char buf[16];/N~ x`F
    int i=0; g^)W#g0IL
    &YY*`;Q?0guT5E7@v
    InitStack(optr); /*用于寄存运算符*/
qy4F4ZPB     InitStack(opnd); /*用于寄存操作数和计算结果*/
k(A&W9x})~l2e&x*M     memset(buf,0,sizeof(buf));+uxU%nY4^:]7q ?
   
[7J/[7NX2U;])g:l Y     printf("Enter your expression:");:}7I@%r'q?/J,K
        
*F0a0p[||6G.f#qD? I     opr_in.ch='#';
Jc!g I*W&W7|/Hk|     Push(optr,opr_in); /*'#'入栈*/.{7U1nm;|6b)H
    GetTop(optr,opr_top);[I3Nbd UdG5R;g
    c=getchar();!y-p,[ U\X'h
    while(c!='='||opr_top.ch!='#')M/Rn1AB"v;J6?
    {
(gFJSZm/Jf         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ {8f;r%r'G_
        {
H2Y&zK:U3Dt#f             buf[i]=c;
i3NU:ll             i++;-qqq|q @Zv
            c=getchar(); @^|?H'y-d
        }6a.r;l zu;k
        else /*是运算符*/8~'A9RKe1K pD
        {
f3QX4t0y1^ g4^{`             buf[i]='\0';
5@s3}/E#xRlh_             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
S{,_~"[             {
*eb%f D3Ur;O$@8k                  opn_in.data=(float)atof(buf);
`l7i Y;@;@-PD:t                  Push(opnd,opn_in);O;V |xxN+RoUNA @
                 printf("opnd入栈:[%f]\n",opn_in.data);"T}YV|0O8\J%B
                 i=0;
7|9P? lz!\8lg5WR                  memset(buf,0,sizeof(buf));4B8[ Ie+TzKq1|
            }`c ~L5j+a#T5m
            opr_in.ch=c;%t5C@*|wW(x.}*t
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
upM8kM h             {
3q,NP%_&gi s"qe5l                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
!wsqS$[-hS*u                      Push(optr,opr_in);4p,_5G9BZ4m
                     printf("optr入栈:[%c]\n",opr_in.ch);
*wso d8yN(I                      c=getchar();I Z8X3EL#h]:`
                     break;
DLh+D1A}*zP C                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
-E+O a&?_7l yF#d0[                      Pop(optr,e);
*y L:LF8^ d1P                      printf("optr出栈:去掉括号\n");
,WZA$R5Z                      c=getchar();U_]:?C9cY
                     break;
)eLv"wvA}4q                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ A"q't:d U jO\g
                     Pop(optr,opr_t);
0D HE?1M                      printf("optr出栈:[%c]\n",opr_t.ch);
I+n0p6}+@ Nbt                      if(Pop(opnd,b)<0)6A8|"C| A8iW
                     {*G&IyV1v8X%Y
                         printf("Bad Input!\n");%}L R C']
                         fflush(stdin);,Hya` aM*h8Z
                         return -1;vHC"Q}
                     }
+?R D3D`([#Fw@!j6U                      printf("opnd出栈:[%f]\n",b.data);7r\7J g,Fh P F
                     if(Pop(opnd,a)<0)+}D9gF$e4_*l*HgS
                     {
O{R6eL                          printf("Bad Input!\n");%X,h n'h@
                         fflush(stdin);h T @.Qx8lh
                         return -1;
n(H.u}9MXcl e                      }
2H.w8F9Jha                      printf("opnd出栈:[%f]\n",a.data);
$w"`Ka\8Dl Z                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
;p$yd;| vev ]m                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
$Uag+w ^}S1[F-h                      printf("结果入栈:[%f]\n",opn_tmp.data);Ex$`7e"L
                     break;
9}w9Y}%d:o6i8ddgz'O             }
;D$w X"l2E0M$v['L} g-R         }+gCen!Q@*O S u%J
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                MaM&dW8n&[4LU{j
    }1d+O Pnb5_+f
    GetTop(opnd,opn_tmp);5MBo MCf%}
    DestroyStack(optr);` p ^;]2ZUC{D G,l
    DestroyStack(opnd);7k^mqNhuF1J
    return opn_tmp.data;
%m\0q"rd'?h9A }
7K o;PN7O-j M$FQ5w
.F|eSAqa_&v \A x R char *killzero(char *res,float result)!b5Q)b]s8~}0qBKa
{Zr;Q2Cx5c
    int i;
CLiN1y9^ ,hbWYhC;i
    sprintf(res,"%f",result);sU;vmd^W"Ug h
    i=(int)strlen(res)-1;
?F {$h`.wV1\v w x8{b     while(i&&res[i]=='0')#XMG.i.z
    {,yP*e+^e5D h%G,[G
        res[i]='\0';
^G}Sr*L%rL         i--;7]F!EF8}8X:NoW
    } z#v.E:MI
    if(res[i]=='.')
a y {9w&O M         res[i]='\0';
7^(e&R ~ P B9v$b     return res;
+^HyH$c*p }
jv*@ J,GbO
o9H3Ow0y"D ]u int main()
bJ(R:w8Ra-b&~x/m {iSj@7\ o3D|2H
    char ch;&O0xH/aKe(c%|I/tfT
    char res[64];
z3V:S6fKgh.f     float result;
&GhsbXW:vo     while(1)
)D-nL!c Xs/r6FL9q     {
}J7x+Q }Y5m [         result=compute();
bpe],A6v#M:d         printf("\nThe result is:%s\n",killzero(res,result));
H0jU+Y2`?         printf("Do you want to continue(y/n)?:") ;
Ls#I;wO         ch=getch();T y.A'qzb
        putchar(ch);^V.g*\#g6q;T
        if(ch=='n'||ch=='N')
6|MV-] P }h             break;
{Pvk`D[         else)dK']mr"@
            system("cls");qNY6YAG Qnj[
    }[tLmu+i,j
    return 0;,S9]vMM-j
}[/i][/i][/i][/i][/i][/i]
0u7G \!qW o W)^ "C$LM&{#P)H{
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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