捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
1[&~C+Y'KIIW&PW 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
I#e,Dk_G2m /**************表达式计算器************/-l2n3h _k/x [.v+^y#]
#include <stdio.h>}6uabl9a6C
#include <stdlib.h>
/| TK ?T #include <string.h>-H B-@t_~
#include <conio.h>
v`$G k1m"k\ #include <malloc.h>
zcU7NBo2cxc $u-uJ0Gp1`/PP
#define STACK_SIZE 100
Q)B,@z;?u #define APPEND_SIZE 10
D1{p}5U2^;QQF %J)ergl ~%[
struct SNode{ R(u;wdC*M@[
    float data; /*存放操作数或者计算结果*/2EafnD$rKh
    char ch; /*存放运算符*/
*?:YBIEKos };
c!|9m0KqNPM[)}9?
-b%zw(Ihg%b struct Stack{%m.IYI!S\
    SNode *top;
WWp'rWK%p     SNode *base;
{D SKB6k     int size;
8m"Z#|1WO~FUf };!Vx'UR%w

S*M:~{:VS{ /*栈操作函数*/
.I!n}_)M&}(} int InitStack(Stack &S); /*创建栈*/\}'u*zHQq` @J&h&}Q
int DestroyStack(Stack &S); /*销毁栈*/,d-rG$}2j wnE
int ClearStack(Stack &S); /*清空栈*/c4W tg.qcp]n g
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
(EmO:|!p-R:|a0] int Push(Stack &S,SNode e); /*将结点e压入栈*/WhV~y'l~'u \]
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/Q/jo+V6I#y
Y?1` a)kXs'@:g P6h1Q
/*表达式计算器相关函数*/
A@.V$` u1WJ char get_precede(char s,char c); /*判断运算符s和c的优先级*/ qBO'z!S/`t
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/-?t)[JSzV
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
\al/k&BHx6sJ float compute(); /*表达式结算器主函数*/
r[$X@:q6S Zv)yK char *killzero(float result); /*去掉结果后面的0*/
N9H/}`}kZ_ FzyT
`{/p+gP int InitStack(Stack &S)S-M]0x p|2m5a
{ORj0R7?IoK
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));me%L`a5x
    if(S.base==NULL)
qJ8@2sn@n,h     {
`6U1T[*?2ne p         printf("动态分配内存失败!");
l8{'o kNV h VPwO$Q:g         return -1;
r.lO.{-a"d"a     }
Ka.M*~;C*Z     S.top=S.base;
qiR,p Nbt     S.size=STACK_SIZE;
@b1J$|(|h,t!w     return 0;^,N'mf3_eb
}jAG8df$St
8o!h2@b!BK%i
int DestroyStack(Stack &S)5Ki1V^z k.pr nA
{
7FXm\D+gm$F K     free(S.base);b+b0[J0Jy3DQs
    return 0;1J3xc(NUm
}
+o)? D`!|"v#m/~;B3E
b:{8gbLcw!`S+^ int ClearStack(Stack &S)"Z.JrvF/NRP Y\
{
h0w&]Q ]7~ N     S.top=S.base; S5M+ux"]/z(q
    return 0;
G(fm}g!F:j5F*fi/W }bx4IB9`.d
f c8Z;BiX.y |G/l2n
int GetTop(Stack S,SNode &e)
6v`+WyA ]SR(J {3LAE1xax:K
    if(S.top==S.base)%B%\vR:V&Uw/y
    {Qv+R(P/qE4g4~
        printf("栈以为空!");%gU:pr'z+m [ Q
        return -1; ITgs(~1d(Mg\a'fK
    }ylR"f/J2Z0Z
    e=*(S.top-1);B9@ OaqE2TXH
    return 0;
0l"K/rL,~ {O6?n }$M;Y+Yuq:\J6g7|3lp%a
:Q#R.x,C],c(@
int Push(Stack &S,SNode e)
2Fq z`)th-tZ {u+l$I O]5e!n
    if(S.top-S.base>=S.size)7agFa:rO
    {
;v YM s8j(~         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
Z2_SF l~!I)JC] [         if(S.base==NULL)
'}Dk/aiu]*|*Qc         {
kjI]F7r             printf("动态分配内存失败!");t\5p \xf
            return -1;H)r4z%zT.B"G!T+}nfa
        }
-W|6qYg         S.top=S.base+S.size;8v)O [o `$rH
        S.size+=APPEND_SIZE;3R U7wu)Vj%H
    }
i3b)x)Js7D%M     *S.top=e;x'~.b/D'cW9p
    S.top++;
q \?JN7i c&h'aO     return 0;
7Vt6j0m(Tx }
oj{ k}*|dq 4tO"Ko I
int Pop(Stack &S,SNode &e)%_9x2^!mlD^
{
&B5A_-O&t-J\/]l     if(S.top==S.base)\(Wd CM,E?,_
    {
k+l(@K.M         printf("栈为空!");V N q%fZH F7b
        return -1;
2Wha&Q*E~7M     }x!otEq+u7?tT
    e=*(S.top-1);v c e2MdA|S0E
    S.top--;E q1x EdA
    return 0;
NL3V|v[ }
2GNfXK
p E:K#q&E@P/n char get_precede(char s,char c)
K| g d.e#i {
X9z ?HT7aI^6Cb     switch(s)
T @:zemV1R:?     {9ZXA(};s
        case '+':                 j+|H&kzzp
        case '-':
5M k0C PMF8|              if(c=='+'||c=='-')
d,\lf4F v/B                  return '>';
,e9g5p,S k2O              else if(c=='*'||c=='/')
Hf3O \7\1MO6McP5q                  return '<';];CT6Ru"}9]*c
             else if(c=='(')
%O2Ti8t mxPOIz                  return '<';#Kw6v+CX g4O
             else if(c==')')
"cjZ1n{                  return '>';
5hlb7{ oJ n"v              else W$B E+RE |1Z S
                 return '>';
!j#BUQ } T         case '*':
hH4v M8zg         case '/':
7Q y;uPs;zb3{)e:p              if(c=='+'||c=='-')
5p3IB*s'V?)[x)N'F                  return '>';/R+[hr ?*e,O
             else if(c=='*'||c=='/')
\ wEe9C8T |iA                  return '>';pUQ} sJ
             else if(c=='(')/vI2y!Xc,l8I
                 return '<'; d1O&F'w [r
             else if(c==')').V$S"@ }[`0vbj p+M
                 return '>';4PVh/Y,NE|~s p
             else
9FuU,yS5m                  return '>';TviS1N
        case '(':
e@t,E:e f6Y;vi              if(c=='+'||c=='-')
7d+m'f2P+G?4Iz&@                  return '<';
.Y}4_wvQy_              else if(c=='*'||c=='/')]#p6Izor?ck
                 return '<';
i'_&F\%B:`)R              else if(c=='(')W pH1wP*h2u[ G
                 return '<';Vw ^:U bA\b6|\%r
             else if(c==')')yO4z#xn,_7n
                 return '=';I*m:]KL O
             elseP#E;L1_w
                 return 'E';
8KP(mV N)g#g         case ')':7s"\+c J)tEA?3^/C
             if(c=='+'||c=='-')
z?'p)s5m ^1ouG                  return '>';*Z,j5U,[D
             else if(c=='*'||c=='/')3nOzw ^ F
                 return '>';$g_k QH
             else if(c=='(')d Y.jc,?,B$hf9S
                 return 'E';S?7n)wM0[)h
             else if(c==')')
E'HJ}~UY                  return '>';N{ A8d/l P9Sz
             elseq;s F&eF'A%z}a
                 return '>';
x!sa/{Q[w         case '#':8@0C4H|yG
             if(c=='+'||c=='-')
R_7{%A;s]od+}                  return '<';
g#hyF)L7{)y{!mT.m              else if(c=='*'||c=='/')1v*C7bY|
                 return '<';:r cv7N&vf M
             else if(c=='(')
FB9qk J@ n                  return '<';
'lhP,rB/XL/F7aia              else if(c==')') Y0oU'Z)|+@T#Kt
                 return 'E';:]r:j#Vws1Z
             else
Z0L:O%|g:\                  return '='; B4}-Ku"PK
        default::[,wC'Upi+d
             break;P n.B,H7^ ^ ~,o j2X
    }1]-oC4P~Z
    return 0;   
j:o8~V4X\n }7J}/A/N-nO
Q[ A N0~K:i_
int isOpr(char c)
{ Av[5Y5P {7N0VcV p2R0RD
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
C;Y"c9i~+LX.k+Fl         return 0;&kTm3HY"`7Bx
    else
}*`G5L.H3M,V~         return 1;
$^.QJ&Ip_S }Ax7vy5YEz0I
~'iPaT:FW6z z
float operate(float x, char opr, float y)
6S ?`!M;ht!x {
s.~#D3H3q{l&b0m     float result;
W-w8xby{9L t&V5pY     switch (opr)
qKT,k7SVi     {(?&L XM?v
        case '+': q6|+g,U3q7u i Z V
             result = x + y;,|(m8t5y+X0y-m/i&B
             break;
9g;Y,d5RR.b \I @V$h?         case '-':
HmU~6v1W+zK              result = x - y;6|m2[3N:XM$Y7K7Y
             break;
2d0wl$@ K(nN         case '*': _(W X+c%y d
             result = x * y;
1J4x^|)}(rf*@$Q              break;
:Fu.Y4I,{%e         case '/':
:E2Gj5c7m              if (y == 0)
S"~%Sq i2C y'F \              {
*W4c+Jp E!J:F                 printf("Divided by zero!\n");'_ eQ}Y'G
                return 0;vRz#E R*PP
             }8?"v pf*B/]9A,Fbm.Uc0F
             else
aAI5K8QT5O]              {
+v'YB'I,B }EA                  result = x / y;,R3fK+`hW
                 break;-u(lV$j$Rw?+PGm
             }MLp} I&{vP
       default: K {-[I5h:U5c
             printf("Bad Input.\n"); tb$BT6O$|h%IAs
             return 0;(e#a-] `!`q9f
    }H yMY ? OK P
    return result;
}GhO)d zA \0_|jl+{ }   
#H*N\0X~x
h'm4yu,G R)] float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
GJ&g$MW#B#@1L4@ {
CB I w+NL&e U,^     Stack optr,opnd;~gf4CI&H\9J
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
!}ZXxI%z     char c;"oJ }e/PX5s d-Y{
    char buf[16];1NLRY E9uq
    int i=0;N)r~+K2[.G3\0y
   
a+CI+l$};c:m2\     InitStack(optr); /*用于寄存运算符*/
2U%HEx*d,V!odAzS1@     InitStack(opnd); /*用于寄存操作数和计算结果*/
7d2L/Z7T F     memset(buf,0,sizeof(buf));q7v4z(e}H b
    {~B cLb)U0D}&u#T
    printf("Enter your expression:");2R2][{8p@i
        zR|zl9Y
    opr_in.ch='#';
Fq`0K Y \;b     Push(optr,opr_in); /*'#'入栈*/
-j"K wSFrZ]&o     GetTop(optr,opr_top); ?"`^:W)\d b.L~2rSs
    c=getchar();
8A1vf[0t#mP     while(c!='='||opr_top.ch!='#')-|H*LM)S x/|
    {5{%q T*ONC!Q7n;B9a
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/B~l frze^(A
        {
O Fd}:^m ^PT5`             buf[i]=c;tEU B+q&z9@5Wr
            i++;;}QBCR:tjXjC
            c=getchar();(Yos7H-Uh,x
        }0EsJhc
        else /*是运算符*/
[q:I8b5_:X         {
C;y^"M+G#Y(xU%ki             buf[i]='\0';$IU+`X+x
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/+moAUBt-nQ
            {
4t*o:`U+gm*Ef"y                  opn_in.data=(float)atof(buf);
SHWv#Y@H5F F                  Push(opnd,opn_in);y'n,~;q*Mb2eb v ?
                 printf("opnd入栈:[%f]\n",opn_in.data);l"Z8S+P9oYi8F
                 i=0;
^ \vWiK                  memset(buf,0,sizeof(buf));
6s%N%tYLa n             }
p C(U(i+vNirhO             opr_in.ch=c;
.i1E!MQ/h3r;hN Y             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/r]a"g"c;wpyh
            {
G6Rm3GzjYShQ j                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
*`A,QAf!F&j5i                      Push(optr,opr_in);
`#MY4jMQCcp                      printf("optr入栈:[%c]\n",opr_in.ch);z^ k_!L;K
                     c=getchar();lt{%lq HN$^m8J8Y
                     break;tzT+~WX(O x3rJ
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
&L0ie5H!T:L&D*cQ                      Pop(optr,e);
0jE)kq Ry                      printf("optr出栈:去掉括号\n");J7aT ]6@'u
                     c=getchar();U%Nu Dj_l)Z{
                     break;t geCk d)O
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
&L5w `+i4W5_8?h w                      Pop(optr,opr_t);
dl o`#bO2Q"_                      printf("optr出栈:[%c]\n",opr_t.ch);
fz0s&msyW/}                      if(Pop(opnd,b)<0)o3f`!N)\X3g
                     {"r/q5uiB
                         printf("Bad Input!\n");0yko']Ju
                         fflush(stdin);e,zarA6{#h
                         return -1;#o7`/d,fe3q Iz!Lo A q
                     }agtjI(x GLn
                     printf("opnd出栈:[%f]\n",b.data);
&}v9n^$V$y i7l6q                      if(Pop(opnd,a)<0)wr7L5kv,\
                     {k s+QLx9ts
                         printf("Bad Input!\n");-dLPCz ]
                         fflush(stdin);3q/XXXqF
                         return -1;
`@Oj8RU+e)e ^                      }
;Yzg6u0MF                      printf("opnd出栈:[%f]\n",a.data);
p6sz5?(hd j[(P3g                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
P8Q\`,E"HVObyA                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
;`c` ]f5^ C)Vr+A                      printf("结果入栈:[%f]\n",opn_tmp.data);.R\~)fukr,h
                     break;
q8B/{T%k'va             }.mx^7^.I[;R W
        }'xh+X p\0MG0x'^
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                E$z Rk`*xC
    }
eDH#`;~2\J.H@y     GetTop(opnd,opn_tmp);
}7Vb*OF     DestroyStack(optr);1z BV|%x!DF
    DestroyStack(opnd);(WcI:n(K;KrC9X
    return opn_tmp.data;
)f-X*xL3w)Rd6d-zo }.O.K~(g|1X/b.d
D/]+H[)A
char *killzero(char *res,float result) K/z},lp$c:d|
{z9B*Rf5j3UD}m4w
    int i; [C6e cD;J;u

)]Ah)\J0}     sprintf(res,"%f",result);
Z U`WwIr}p:~     i=(int)strlen(res)-1;
:ke _w0{(uu!LY     while(i&&res[i]=='0')s gCI9W*@)x
    {
.n2V5m%O`j         res[i]='\0';JCL l#^ V|{
        i--; Y\j4`P!a6H
    }
9C)H4xA9L g2E2@i"@     if(res[i]=='.')P9e%_x J GUn6z
        res[i]='\0';X8abv H}"[8~0},S
    return res;4m0g(d0TgT R
}v \Q*|4^K#c,E1HH
%Ek v*q4M#th
int main()
syTOHi`r {g O*C)On^GA
    char ch;
|~ |PF     char res[64];
^5Wicb     float result;
^9y4r#D*m     while(1)
N0[hr%l O!T'X     {
abDx P\$|         result=compute();
;`)] jgX1sd^         printf("\nThe result is:%s\n",killzero(res,result));o D C^KBN#v#x {
        printf("Do you want to continue(y/n)?:") ;%B:J3f6J7dsa
        ch=getch();
gT~,myE         putchar(ch);
4p vZk)I{H P         if(ch=='n'||ch=='N')
h|Z p8\P s             break;(_H JQ'vC(wF&d)t2p
        else
3x#o L5v4B+b5]             system("cls"); d(RW*^e%Y \Y
    }
~6l+z!FX{     return 0;
+\q{-Y3V7H }[/i][/i][/i][/i][/i][/i]{ |9Z`2D!B

ncOy J D*PFq [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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