捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
V K \#q*p^O w-} 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
r3rh7Z s /**************表达式计算器************/5~Y'x@e
#include <stdio.h>
vAG5hk6kxh-A #include <stdlib.h>
z Q*PWDZ8@ #include <string.h>W-Hp-Z#fa2yB
#include <conio.h>TBb(z T
#include <malloc.h>N/[f+T(w5F6T

'?2tK N9i{Uv|*g #define STACK_SIZE 100
*k$|yP7px #define APPEND_SIZE 10
\$t~y gf$? X 5F$|g7^{$W~I Q
struct SNode{m2xE3\%z&XO%s
    float data; /*存放操作数或者计算结果*/4w,r%~BIGX d
    char ch; /*存放运算符*/(]%V+Lmyb"d/H
};
#}1HOzxa%B+Z
-q.yw&XW]8J6K2~ ? struct Stack{
|ZQB&ye5w&y\*X     SNode *top; [0q-U2Gpl
    SNode *base;VZ,E%C\ Y
    int size;
f.b7g,EV,Vw"hl };
Q p"i pol:] _#C5pXeqdT+B
/*栈操作函数*/
V p j9Q-g0l|? int InitStack(Stack &S); /*创建栈*/ etF5n9s$i
int DestroyStack(Stack &S); /*销毁栈*/t JK,T/d!x:y
int ClearStack(Stack &S); /*清空栈*/
8b1xye4R/[&L1i'D int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/"}*s6o-z(D!a0F
int Push(Stack &S,SNode e); /*将结点e压入栈*/5sl`:T8s*]k5O6R
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/eW"}2LoA
Tb-g g2N Ot,J,?
/*表达式计算器相关函数*/ z;TD V2^!caT Y
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
I4n:Hi6nmo']9S int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
c9C0q zs C'p4Jo float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/4az(W4U k9rR7gg gH
float compute(); /*表达式结算器主函数*/;Caw!lF'H*C({
char *killzero(float result); /*去掉结果后面的0*/
U6sk SY l-r iC9j?qU;u
int InitStack(Stack &S)
u1O2g!waYn9cla {
+{:[8Q}R,A px(?~'S     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));*{%AvD:F t
    if(S.base==NULL)
aD-]N!o l2ki`;r     {*jL9y SZ-K)J|*G
        printf("动态分配内存失败!");f _5fu-LE
        return -1;
o%i?:C:J     }
*y0Nr;D:gK     S.top=S.base;;yH dn6\Vc
    S.size=STACK_SIZE;8Zr+K!|+Bp
    return 0;
9J3k8W(Q F]BT }
?/_;D2\c;aV `0K+qnGY'E
int DestroyStack(Stack &S)cP _0t9b nJ6y'[g
{Upjc&_ i2X
    free(S.base); y;}*rl6A
    return 0;`+A}1q}M/Vk
}
z,`!L1S$K `bBw y:?.|I,A0Ll6WM8KZD)J^
int ClearStack(Stack &S)'Ukp qN
{i} i\ gg
    S.top=S.base;
V4g1Z$@;]%f     return 0;Ohx#^~
}
i |P2A'd"yx'] 2CPkZC0\F9[,T
int GetTop(Stack S,SNode &e)
@|ESZ,m3s {.Qp4Jccd
    if(S.top==S.base) V VnzZ V)d5t
    {'O-R3F iAvw%p
        printf("栈以为空!");%j`AQ^'X-u
        return -1;6l?-\v$`7v8B
    }/Y y(]h3vQK
    e=*(S.top-1);
iMc0fq.s j,p     return 0;
4]ycY5kk } n9DJ{uF,kK!qD
p*d8L"M/x*Hn
int Push(Stack &S,SNode e)
8Z${ L ^+pA\ f {{&Ap8_8D.c%g)n
    if(S.top-S.base>=S.size)q&A*l#kAa
    {
~;YSc[/qL*oY2s9O0ZL         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
?}.} q5BIz6W         if(S.base==NULL) Yu&m9p9{,Ze9L
        {!BF&U q1r$Z
            printf("动态分配内存失败!");+@x W%{'T4H%s,e
            return -1;PK#w,sD`#E A
        }
i8{t`8V         S.top=S.base+S.size;-c!}3mEd+P O6l-O!X
        S.size+=APPEND_SIZE;9suxKD!i
    }
y/s3Zv J-o'z-X8JL     *S.top=e; @-G9~lf.QS
    S.top++;0QcRQX9x8X
    return 0; E v^3awP
}
E*DBu1o(j cEoy
S;v0C S1R Mu-Z#@ int Pop(Stack &S,SNode &e)
zc$l,K:~|8t6Q@ { VUC^y8\A4~'o0O
    if(S.top==S.base)
V v;w1|!s:p_G     {T;\9z.ko
        printf("栈为空!");X8v%M |#B
        return -1;
FY;r MwZB     },X.D)J;x*~H|c&m
    e=*(S.top-1);
5G O7Hw*Y@-L!tt     S.top--;
h/?/|K'|'W;Xm ac     return 0;
fd%a;} ^7B t6~e }
.z'R%{4Fe&hw W ;ar e)AQ s)N
char get_precede(char s,char c).H$zn8V@&Wc3]e0vy
{
~W~#dd*\6oX~;w     switch(s)b(n XP6^N D7q
    {ZV3[6B@c a
        case '+':                 
%n~3lje ec!x3L6O         case '-':W]$k!Acht2l
             if(c=='+'||c=='-')
4u-A5j j d uRz/QFU                  return '>';
gXh*]A B!P.H              else if(c=='*'||c=='/')
'a6[C [8F ^V8p3P                  return '<';
)L3S+[i"XB,P              else if(c=='(')ya^e&?
                 return '<';3w6dw6nZ3R%|)|&\S4e
             else if(c==')')|*LdSDE*o
                 return '>';
/R#W]Rq I,l4y              else 8}6a(o2hR
                 return '>';bLa%@S
        case '*':+V t+HY*zx
        case '/':
m N0M'ENe5a&@J8JE\              if(c=='+'||c=='-')#QQn&Q6k6F9Sj7R
                 return '>';
(ke6z/ec              else if(c=='*'||c=='/')
KI#YRN*r                  return '>';
8jy[+XS ^              else if(c=='(');U1Zi o4GL*n
                 return '<';
bxmB:sCQm0}1t              else if(c==')')1?U u@,B:I6XgD/wB
                 return '>'; avs6u5U[ v
             elsef8KWE C0Do
                 return '>';
W$t4toE0DA E         case '(':3tr!Y6Z5{nrk
             if(c=='+'||c=='-')n.X%c4~:g
                 return '<';h `\K o3INK1w8}
             else if(c=='*'||c=='/')\2U*o7jTDfl5Y?
                 return '<';
-d/M*xge3C_c              else if(c=='(')
(tj2ADW5s]n                  return '<';
3[)S7X+C `9]              else if(c==')')
6IQ_ _r7lH                  return '=';
QH[ K?&H _~ C9x7b              else
;ekS#oQ]H/IS                  return 'E'; Cm1ZJ{*d2BX
        case ')':)b&DP4~t)AX u+L
             if(c=='+'||c=='-'),E0lhW-xcy"F
                 return '>';
qB hj/w)g              else if(c=='*'||c=='/')
'x0?0CF_a#eF)P                  return '>';
.U5m3u{7AYJ              else if(c=='(')L+}'Qr+S2p
                 return 'E';
b4W(eljF              else if(c==')')W/?u7G,@(z
                 return '>';N(SV W!v|n wT
             else
'YpI"}"Y:r hT                  return '>';x o/s[8O/LRw
        case '#':
] |w%u+x-V,f              if(c=='+'||c=='-')5b0o}]"mh I$L
                 return '<';
&W r3g4fl*TYM(d zf              else if(c=='*'||c=='/')^0~ IL\^-Xfyk
                 return '<';
7I6[|u4p3iENU              else if(c=='(')
Y{:at![ }                  return '<';
l!k])h\ OG$vf;z)HXf              else if(c==')')
dvo(Jh                  return 'E';
dt\e-Fy1|1`t              else
Ny,aRGY                  return '=';Ik Z/gW^@6]5Z
        default:
q7\PsFd`U              break;
^ _pR[ O     }
%i)_8J9} ?!cU _ y q     return 0;    xj/i"XH
}
k(H&N"GmG2u!g
*s5d yj0jH"RM+eQ @ int isOpr(char c)(N{ i"s8^Fi0d:c
{
;V#b9Au#J]     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')I+K Q;G!x
        return 0;m;F q?/afjy;j
    else
Fw~Rm0E4B         return 1;
I(C"ca6l!R }^gLd)J+Y)F`7p&~
~EUC0e2j
float operate(float x, char opr, float y) _!b6A{ ` D[
{
&@H } r9o @^     float result;.H%{2r@U
    switch (opr)
S-`"y:h#R] l&t&Q6M|     {
Bn"O(Yef?+f         case '+': m*[ST.e
             result = x + y;.D-C7WM5Qj8`A E4s ` R
             break;
)g@%? D }w5w F4B         case '-':
"Gym&~h1N*a z0w              result = x - y;
c!gZ(n6`&S!hll              break;(L'[]B D?i
        case '*': &G]2q4q7oJs4F:^,@1c+f
             result = x * y;
dI0P9Q Ew,h K              break;4x:M7_G h{c
        case '/': ipS6V:xw"R1x
             if (y == 0)
h0[j*]_6Jv              {gyQa"A6wsp'E
                printf("Divided by zero!\n");
"^gtoS8V J                 return 0;
.hOR:\F)R i |              }c,z-zk*qS+p
             else
xIsr4|(k/l{              {$e9U!}x VD]U-KH v
                 result = x / y;H \WE/VN
                 break;.~HXvRo2]
             }
&HNz{Rz~w        default: vfz VEw+VaF&b
             printf("Bad Input.\n"); !L|H f2r \%KQ
             return 0;*F6_6@m.B/S
    }
R(bh)^ Nv?T     return result;%aW2N5XnV9t2d\0?
}    @3c4x6?_9\1`X
/}W&s?lvxlU2l
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
I(do3N*Eoy {-v YT P$v a
    Stack optr,opnd;
`-Y%W.w [eLC2U#f     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
6pNi+Y[%J4f d\QVN     char c; |w-Y |g C|
    char buf[16];fI6U}4T4JFk"S h
    int i=0;;u2lO9f*l
   
pRB h@1@p     InitStack(optr); /*用于寄存运算符*/ D7lI-ws%g1\j V
    InitStack(opnd); /*用于寄存操作数和计算结果*/vZ'R^|^"`
    memset(buf,0,sizeof(buf));'z"|!|lkA@ E
    q^lX1U&L
    printf("Enter your expression:");
)It0]8z q         5~B3aY_Sf\f
    opr_in.ch='#';
.DgmW)keN     Push(optr,opr_in); /*'#'入栈*/
v;H8f2qV~6x     GetTop(optr,opr_top);9x\8L5I,{K#M
    c=getchar();
$Q6^ JG![^{     while(c!='='||opr_top.ch!='#')
6\W2\AWczP\     {
-M*?c,\SL8Iu         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/7D#k*nlRv0F
        {
5n-qx"Gy5x~             buf[i]=c;C0{r5?yc&N
            i++;#Q0`7vw7qL
            c=getchar();
'_N*i+P}[         }
-X)G^-o W B7wn~7?         else /*是运算符*/TH-A7q4mBF:c
        {
7[.d m0N `a             buf[i]='\0';
sFzd%e"I!_h#s             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
r$zxrl6kDn1`             {B7_Dh&~2}"e*j
                 opn_in.data=(float)atof(buf);
Eb3D1FQ5Ia                  Push(opnd,opn_in);4?RH0}vuA
                 printf("opnd入栈:[%f]\n",opn_in.data);
7e#S~ W2J                  i=0;i ]/?WH$mt)~#Q
                 memset(buf,0,sizeof(buf));Ufx5CfP
            }s8g(lc?(Of
            opr_in.ch=c;
%F(A9e6]s5M R7|pw1{             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/S"Ww:O"U/s
            {
V@T(z8tAG                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
?L_Xn9J                      Push(optr,opr_in);
M'x;} RW1Q                      printf("optr入栈:[%c]\n",opr_in.ch);cn G1h'?n3@Q"r7o
                     c=getchar();@!OP!Q WY$PU'a
                     break;
K_x;?h ]                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/S0IU:ft1f:`ZE;U
                     Pop(optr,e);(x }DHm
                     printf("optr出栈:去掉括号\n");
j/kT7k P2MxM6KF                      c=getchar();
}f P8j,S&~]                      break;
wZjI`0W                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/*A g:AP"s-ZU:V
                     Pop(optr,opr_t);B al@:m:M&@
                     printf("optr出栈:[%c]\n",opr_t.ch);q8`*fLuN(vG
                     if(Pop(opnd,b)<0)'Q&Tw+Y z'[*j k7R
                     {
;j0v{F|[ lG                          printf("Bad Input!\n");
p@ Z7@V6U                          fflush(stdin);
k)D,PbO-`.q                          return -1;+z~A]4|
                     }/k6MU-U)w
                     printf("opnd出栈:[%f]\n",b.data);
3_,SL5I5h4}%w                      if(Pop(opnd,a)<0) m8Y2e]8dHA7o n
                     {U_k^k*s
                         printf("Bad Input!\n"); Z1[G0| ]D[N
                         fflush(stdin);m\/q8^^*Ceu&Wcx
                         return -1;
0B!M zpl!WG                      }Mn-L4b$NS!Q
                     printf("opnd出栈:[%f]\n",a.data);
R7f*x9{ |g}!M                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
.t9H3N f'~qT)W                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/6W!B5o Y-N8YCp
                     printf("结果入栈:[%f]\n",opn_tmp.data);}9j i8x*fzT
                     break;f%B*K:H5jk
            }(nw.M*g d]#eK
        }S,mE)tcA)rx1\ N
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                /p3fEadM U(c-T
    }
#Ip"T*j Y*^#i^     GetTop(opnd,opn_tmp);
X z7s {dc     DestroyStack(optr);F)x Wt0`
    DestroyStack(opnd);.X JH S!CS|9G
    return opn_tmp.data;F#[,wv*s#j*r5^
}7LPV5zL&A]

b GA1if| char *killzero(char *res,float result)
V|_7g'E9CP'm {
V c'RM'U {}B     int i;
ec6n6k3r
KX3a"ud3u r(?6`D     sprintf(res,"%f",result);
]9EIEX fx:^     i=(int)strlen(res)-1;(t5VI.D)IB:xRq
    while(i&&res[i]=='0')
;X.U7`\$J9z5u     {/I[P v JJ I
        res[i]='\0';
X@y E:[-W0jXV(X         i--;UU @3Ey8RLDkh
    } c2a,so#X'd-v(yt c
    if(res[i]=='.'))r$KS(LQ*u B F$ze,F
        res[i]='\0';
Oc4v?#b{ c$_ MZ     return res;
'U#Q]"A}E }0V:r I1S7{+bQViZY
\;|7{0N gOl"F^ bk.~
int main()
}+Nw]/\9k:ihO {
SJI(qJn W^j*]4[#i     char ch;
$DaB&`Qt+z     char res[64];5esO2h7Hj8x,g
    float result; F!B6Gi\ H xW
    while(1)#e ` LPR$ka?8b
    {
!j]L3^%Q9K1s.k4~)Iw8q         result=compute();
"B z4FWZ;@r         printf("\nThe result is:%s\n",killzero(res,result));:@+}DC$T&cu&sg
        printf("Do you want to continue(y/n)?:") ;']4fzj:hZ|F
        ch=getch();
"wMk*Gy(Q%l         putchar(ch);z8T'{SU6[(l
        if(ch=='n'||ch=='N')nG!]dkF{E$}f
            break;1j;S$e Cu/kW
        else
a `G/j1\H.iMe#@             system("cls");
y+zB V9@&y     }
#g~!c Dq(r3wE     return 0;a2wvBvoU
}[/i][/i][/i][/i][/i][/i]
2JY[?UxU!P B
r{5R"^zm [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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