捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
:Y?*K lz$hm^ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=)\Jn/Z0{:zs
/**************表达式计算器************/(Ex5wH1? Z"lt6r\(x)|
#include <stdio.h>tdI(b fe
#include <stdlib.h>
i&lVr |fE\ #include <string.h>
3j8i]7p;f(?C!y K #include <conio.h>s8dl*d0s0h$R
#include <malloc.h>"I)gQx1z:DLk
j#h?+o"N_ H*[G#N
#define STACK_SIZE 100
9T$h7|'C&c3K;Y'x(\/]-E #define APPEND_SIZE 10c7s Y~O

| {9\ u4[r struct SNode{~` Bo2s@ ?
    float data; /*存放操作数或者计算结果*/
[n1EKf f7N`,HaL     char ch; /*存放运算符*/VGSn n v}.?
};
T,HjB}t 5b4B#e `+?b
struct Stack{
AvJ^6q!{dx     SNode *top;] M7a/Y$ac
    SNode *base;:M!`QPOub)n5m
    int size;E%@'[3[5F'Cc(S
};Lm"W ^8X}
#Uv6}]GnFft7I^B
/*栈操作函数*/2fZDGLk0LT
int InitStack(Stack &S); /*创建栈*/
1Y:RIcE G int DestroyStack(Stack &S); /*销毁栈*/&bm5x u#{8}
int ClearStack(Stack &S); /*清空栈*/
6l p+[J5^/} int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/;N|W6N ~-[
int Push(Stack &S,SNode e); /*将结点e压入栈*/Ib v4s,o^3M
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/"N0wNS q!l9PX(O\?

z%N"E,{}+X /*表达式计算器相关函数*/
2w*m%Z#n&{+x;_'Lw&qa char get_precede(char s,char c); /*判断运算符s和c的优先级*/5iQKQp7e LgI
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/.Zk? O.TH/vC o I3z
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/})hQsgH)f
float compute(); /*表达式结算器主函数*/
0S*V,vCA C*[K char *killzero(float result); /*去掉结果后面的0*/
}S,Eq,|!{k
8y7N2C$|&Q1f:q;k9}+w int InitStack(Stack &S)E"R7N E8k%v G,qI7X2Q
{6T*x~L8Q k5v
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));!@J1J.c|i q7^Dh2]
    if(S.base==NULL)
p!Eh%zy:bx     {$W#C G,Y4l&B1p
        printf("动态分配内存失败!");Da2yu)f/O%v
        return -1;IGL9zO-u:_6Y
    }
"aBU0w^c"}2G'~3S{     S.top=S.base;
H;r#Y Y@c(K     S.size=STACK_SIZE;
K:D r)` GM.hRe[KD/L     return 0; O%Xv I[u:Y8_
}
lSlyH/ErL4R DW fEj;?e!D
int DestroyStack(Stack &S)6DW8q8^2a [;X'][ II
{%[RkC$|2e#t0mL;v&nzJ
    free(S.base);%b'S{,l"\7t-Qh$T0ZZ
    return 0;
_S4Z#W&J0T }
? Y:{l$N*YY b
/C%v;[(A I int ClearStack(Stack &S),qc8BHH'@r!^nu
{
$Q~[/iDc1^~ r     S.top=S.base;
fv!cV!iq8T     return 0;
C5hX4CXL0v1U }"xu }}u9S

W'Y6E*Q:s:Dr*A int GetTop(Stack S,SNode &e)
T)A3be-NC&V {&v:E+r-ec4P F\"x
    if(S.top==S.base)_'@GX6\u
    {"eKLY;eM g
        printf("栈以为空!"); x.uEH Jt'w;_"z
        return -1;WoOgdio
    }
C?.lpnO9{ ~4d     e=*(S.top-1);/poswa~%lI
    return 0;
\t9CS'\ W!I-{f }~~ wT(eNP gi

NT`Ba int Push(Stack &S,SNode e)0pF&Y|)O"Z
{y2[9`5X"|
    if(S.top-S.base>=S.size)3xu8?,FoB#O
    { Ur Npr0s
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));b WLF/c:\9U
        if(S.base==NULL)!}d8i0w^6pV7Y,o
        {
h,Q3^-s2D4|0J7t             printf("动态分配内存失败!");*Gm9Vrco o J
            return -1;
8uLYt-lG!kU         }7H P1AVA'e:[
        S.top=S.base+S.size;
]3C}n2H^         S.size+=APPEND_SIZE;
o \V'?W @V     } k }7CpO
    *S.top=e;
g-Y8h-i&y.t4H     S.top++;
6o_l1\;{v     return 0;&Y i"\*m'qQM
}
#E B#X,c`e m|'O\ c6N$Q't2Z4zE5Z+nR
int Pop(Stack &S,SNode &e)
\G b ^-i+Sq+@OpW {
?8u$p:Z A     if(S.top==S.base)
vs8Gjm     {
JNJ T wN$n"P9c         printf("栈为空!"); mFL|6P
        return -1;t.D3f(YBN*@n4_Ot
    }3a+\d)B6dE3g ^(k
    e=*(S.top-1);
WNL|*N QRX     S.top--;LxW4YH
    return 0;jDb#X D tt
}3^,QA t Hs/|3a5kV-hL
+mA(JGT Y#O-\
char get_precede(char s,char c)
CSVIl {/y9wRbz/dcY&u
    switch(s)0t*Y tH@zK[Z
    {~ ieF[ }"V
        case '+':                 
5X,{z4I zqe         case '-':/Nh8t X4h%BS
             if(c=='+'||c=='-')
:?m/`K y6iE                  return '>';
F4h/Z?_4CMV              else if(c=='*'||c=='/')-ti+i i3K E(yW+K(iU
                 return '<'; Tvh5_{ }
             else if(c=='(')\)ZS!r-w8q
                 return '<';z8ht*Y/iGl'KB
             else if(c==')')
S:Y!l"_8W4Z                  return '>';2N9YbS _#wy
             else *e(u? e o6K+_v? Lw}
                 return '>';
` ? E Y)N7\         case '*':
)o$X a)Fs+z7Q         case '/':v.xQ Cjz7I6K(WU}&r
             if(c=='+'||c=='-')
w:|1io9G                  return '>';+D P5yBq~^
             else if(c=='*'||c=='/')
DY*pN O[                  return '>';
xn(o&Lip$Qo1?              else if(c=='(')
9o'c1k7P}8S @(~:[                  return '<';
?#i$ZSfza              else if(c==')')O'GX*q` e f{*w(n.p
                 return '>';
x3]}lz0o              else
+nU9P-J['J5X                  return '>'; m`wz Mu7u
        case '(':
X{T&l8}*H*~0B              if(c=='+'||c=='-')#Z;J n&N%QS1G"`(W.WG z
                 return '<';
@ZB"w5|L mA              else if(c=='*'||c=='/')
$b7Ak$V mD                  return '<';
5]:S"ct#i*\G`t7u              else if(c=='(')
trRa+Q                  return '<';B`}/uU'x"s
             else if(c==')')
g#N:It&HB?+]9xy0i                  return '=';
b1y3RA0Qx%SD3@g              elseOU_,q_:{ \+j^^
                 return 'E';
W/r H-n2] J         case ')': v9Zm/O2P%O I WBt6{ R!gR
             if(c=='+'||c=='-')
R2oOo4Yj\                  return '>';
K_9q8d8I#A              else if(c=='*'||c=='/')
ik-M zj L                  return '>';
l;Ds;X+Q!t              else if(c=='(')F"l4h,Kn)KB&M,u
                 return 'E';i} w3Wu
             else if(c==')')
q} D{,{3\%X@/[%B/f                  return '>';
c&u4p4U!J??p              else i0bi#L n.@B(R.L
                 return '>';cI(Qb2ea }pC
        case '#':
Uu_OZ5TO%C              if(c=='+'||c=='-')z0`7Bh;cpI)a
                 return '<';H1KXD3A$gN8s
             else if(c=='*'||c=='/')
t xEBWO8m.F!ui                  return '<';W5Q+B.MAD2Y\.a?3Z
             else if(c=='(')
B+u4uEY D*?6uW                  return '<';
G+h\(J"|ZP              else if(c==')')Q%QN%c+{
                 return 'E';
UE*hl%{G3@@*G/B              else
i/`A Hlb"j d4Q)~                  return '=';
"q}e;??,r-E         default:,qO6zi6Y
             break; Qe,^H?$mcF2R
    }
*n;d9h:aJ Wk     return 0;   
S*Gkw,S:m }
w?w]OX iUjTk5sPN
int isOpr(char c)
LnED_ ~o5dH&b {
sr l~C6l     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
0M#uE m[ \N         return 0;
Q-v7ts^9mY     else 'T l4`#@)N ^~on
        return 1;
3~I c f {[Mud }y Vb5B2G,|jG'[

\i.H m,{ float operate(float x, char opr, float y)k9D;Q7|j\T
{
z Q!_ O]/_~K+[+U     float result;
%cr%Y^7u,y     switch (opr))O6Wm'G QL
    {F(I&|@;b+diR
        case '+': e Y1]x-vt4}7J
             result = x + y;
+{0Z_'c'bLU@ p              break;f&OV3gXh)W)f
        case '-': AG;Fr)\A}(x {
             result = x - y;
c(Dq;v!ny D              break; ~k,I_r;BV
        case '*':
&om5tz2y6G$M              result = x * y;1T {0dK1{8nQ
             break;3hL"oA(?
        case '/':
;F!_4K3Zz[3Y              if (y == 0)#xz },sa%l!Tm:`
             {se~,N.e3M
                printf("Divided by zero!\n");
;uM W'{5\"?kjW@                 return 0;idX,Ud)bo
             }
#v_"[4F5d(O              else
Q9]){-N1[B,Mj#N              {
5Mm'[T(l4r_6d                  result = x / y;
(F%}-u6v-|6Z%gk                  break;
5ZJ3i2Me-a$c&a              }
0P` s[ me6E^:q        default:
r|g+sQ(KwN              printf("Bad Input.\n");
.uw c2U-CaW              return 0;NQO uLn X `$?
    }4k ze8c3rS
    return result;
{b4}2p1}Z,j }    (f}+G{ S&_

f~/ySes@ bFL float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/1e g H3V a%fV
{,f0Zq-m&O.HI0ZQ3~
    Stack optr,opnd;1t)Yh)S(j&Y
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;Un*hrWT5{!g?-h
    char c;2C)o k@?|(F(U
    char buf[16];sCYQL
    int i=0;CiO s+p8{
   
m6P@-s#K _ VR     InitStack(optr); /*用于寄存运算符*/
)b e*j'p5Ke:`     InitStack(opnd); /*用于寄存操作数和计算结果*/
!y+d`cea     memset(buf,0,sizeof(buf));
Tt1ds4qHe    
/ZH%e3qL#O1k     printf("Enter your expression:");
5|J(iF`8C{         1es4IGk K1fv(Z+A]
    opr_in.ch='#';9T0I4^"k9_0WD
    Push(optr,opr_in); /*'#'入栈*/
*}(y;j6vu     GetTop(optr,opr_top); mN _q$}kQ
    c=getchar();!Q:zr;z6g$Dd;S
    while(c!='='||opr_top.ch!='#')$^)a"o"E b3^
    { s:I*F(y'}L&K [*K$_
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
,K(pF(z]6v%}J         {L&IE|W ^ ?
            buf[i]=c;p'Y\G.`~,}
            i++;lB)SHnF
            c=getchar();,?w9LA.|5^+S
        }'I|4F${dh"s]
        else /*是运算符*/,j1|@0i&c~:ZT2^
        {
;Ua.@l?@/OG             buf[i]='\0';NUf%t,@8YcV
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ m-Gl8f_v
            {"gL(Mv2z
                 opn_in.data=(float)atof(buf);6_(T l'a'e2Dh9uly
                 Push(opnd,opn_in);J^ ~,r)BJ%B
                 printf("opnd入栈:[%f]\n",opn_in.data);|.B0rs'G FG*?
                 i=0;
6V-d(w#`Ou$z7D                  memset(buf,0,sizeof(buf));
2[1\-Cspd [             }
}Oo@#["t:] Y7r             opr_in.ch=c;k4{1Fd7\_#g F
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/"S5Q;BcM'o c.Y%a%\
            {
'hm-B.H{k                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
|lIE {'^                      Push(optr,opr_in);3?+R)CP"s
                     printf("optr入栈:[%c]\n",opr_in.ch);
F"Q$V4ws"w6O                      c=getchar();Vm D1Yae.n-`"B
                     break;
+Mg(I]T&|5B V                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
.og[-e#r,X,c#l                      Pop(optr,e);
D awl&yW4b                      printf("optr出栈:去掉括号\n");#[2de:U!Hpme
                     c=getchar();(Gf"_3~ HqOt
                     break;
yg`I'aalx,t                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
z)f&RAu,c ]pu                      Pop(optr,opr_t);
I-T5_v{ dP                      printf("optr出栈:[%c]\n",opr_t.ch);S@3wl6HRyoh
                     if(Pop(opnd,b)<0)
P%W(O?"u0C?:U+~8Z                      {
tpp9Cq                          printf("Bad Input!\n");t3?!WxT)j!f
                         fflush(stdin);A\F#X? V;E Z
                         return -1;6nT6A~3UE u.k t m
                     }'G3uY8vR CI+X_
                     printf("opnd出栈:[%f]\n",b.data);(lEs6eU!Jgh.\K~n
                     if(Pop(opnd,a)<0)X?N$Y&r
                     {]-vw jQ'l'S
                         printf("Bad Input!\n");
VcK g&^0pO?                          fflush(stdin);
_`1o(F2]                          return -1;
,Q N V]cqI Hi"U                      }4_t-|l5H8E^
                     printf("opnd出栈:[%f]\n",a.data);F,L|(Tza6EA0o
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/2@HO wn
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/-Z7PK)I^&W
                     printf("结果入栈:[%f]\n",opn_tmp.data);7H[g%E~S
                     break;
:XGQ[!A:\6P(K0P             }@+pD&A;iX7x/T Y[5Z
        }
]uDa Te         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                dOZ mi
    }
,EAGT1o i {     GetTop(opnd,opn_tmp);N a2Ya6guh8z
    DestroyStack(optr);/F-jX`\}DT+w
    DestroyStack(opnd);
H"JuO3eYbV7V     return opn_tmp.data;$D;zOl^4r ipE"p
}8I3e2ck%euV
%T%H epfjd
char *killzero(char *res,float result)
y.I?Y7rbJ)h ~,c4H {
_:z7m0Qz     int i;
#f4?T|3G$XLe6a#d0Y@
1D|hV5P R"J+oex+Kp     sprintf(res,"%f",result);
\'Wr T+^{Eg     i=(int)strlen(res)-1;,q,}x:i2S,dF]
    while(i&&res[i]=='0')7SF(a6M"RS|
    {bt1lM1O@q
        res[i]='\0';;A:mA,c erDm_!O
        i--;!~:I?'~g}2B7oXf+Q
    }"bk n0o@4By;w
    if(res[i]=='.'):t#TXa[&Yj1S]N/t
        res[i]='\0';
dT3a@p     return res;X{7O4r'L!P m\
}bXE7V,|4t J_(R*e5V5a

q/X/aJj int main()+tR lqd7k Y{
{c:h @)U']v
    char ch;Du6I)? K
    char res[64];Y5[X]jq.j&]!s2e
    float result;C+pol2^*O4Y s`
    while(1)
cX#G+W(fL*at     {f4c1TX@?#G
        result=compute();sieTz#[U
        printf("\nThe result is:%s\n",killzero(res,result));
en s(t;Kw$]o!w;_         printf("Do you want to continue(y/n)?:") ;
.\)G@+V([+}(Z n2[         ch=getch();
O3S3Ly;n Y$w-W         putchar(ch);
5wTJ4cIl.Y         if(ch=='n'||ch=='N')
:f.E&?@j-[             break;R;h0[)rzkRM
        else
FTS&?f7}L&G             system("cls");
k4VQ"\S"}?3X     }G+S)Rh3_ d(PM5Mi"_(~"f
    return 0;$['b$h$m+X;Q$mvs6N
}[/i][/i][/i][/i][/i][/i]&a-Q/c If E

x6Nn;Q)L2{}MW[ [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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