捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. RLYN]h
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=D |3vmC(H%M4[M[
/**************表达式计算器************/
-se*p1U9^RN+R.j #include <stdio.h>
'I"O+| O.M8s X1i.a;q #include <stdlib.h>
6A_"yR)t{do #include <string.h>
6f,b%J g$G$})H #include <conio.h>
7tA3`|,o _*j.f #include <malloc.h>-V"Fd,sNN(k`
s(jDU.O
#define STACK_SIZE 100u,`5f/ocj
#define APPEND_SIZE 10y8](|] n1v_

u"N,`QEB!mE struct SNode{,R%kq/T2GM*k5kp
    float data; /*存放操作数或者计算结果*/ U^0oz)WPT{5jW
    char ch; /*存放运算符*/n[ y1Og-r(|{Q
};
'sX(jOe
`-`#M:R MK'l[ struct Stack{,}^,B0]$TceP4O
    SNode *top;.mwA brA!q y
    SNode *base;
D bo"v}YC8O$V     int size;
7s] aAWd,Q };
,@Ln!M.f4Sp;u"h5C~
_ U(?}NHQ /*栈操作函数*/ r)F&k dp\Md@
int InitStack(Stack &S); /*创建栈*/
#_-v%ta1Ma ? int DestroyStack(Stack &S); /*销毁栈*/
;~8h,A` `p0TNp int ClearStack(Stack &S); /*清空栈*/RL;x9B*}6V
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
f$h"WTV"Z int Push(Stack &S,SNode e); /*将结点e压入栈*/
ef C1Xv)l7Sov int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/SIS;x\ZFL
Z"A&N$f B%bqW3I(]
/*表达式计算器相关函数*/
hT#_oa#T char get_precede(char s,char c); /*判断运算符s和c的优先级*/1@"Qj9c!c/h?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
e7\,|(Q;B7m&h float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
S8p/|\2O"R,X o%b float compute(); /*表达式结算器主函数*/#gCL!J!xHC
char *killzero(float result); /*去掉结果后面的0*/ /be*{S+@%Q1_ s@Op
[M9V:_A;W*@%k
int InitStack(Stack &S)
IMSr_8c1m;o {
4TlcjC)`:~     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); [A$v!PXx
    if(S.base==NULL)P5[FQ2?8e
    {A&H4Qe|5RV P
        printf("动态分配内存失败!");
r#xl9@qq.f$e+L @         return -1;#Z L S ^ ]hfD
    }4G/g"Y5WO,{
    S.top=S.base;
Hn]z%]0D KE[     S.size=STACK_SIZE;
(j ek#| Se q \[     return 0;\FE6OQ
}
+Us3og U"v ]Ypr
Z3~,WGL int DestroyStack(Stack &S)
p|5rT4\|$Yr` {,zeb7]k m'aP'W |S
    free(S.base);Q.j}q k)r%b
    return 0;)Nv+?3x6J h[,J9R
},Y/e lh5E^(K W
8qt#G%w,S%{k7[#{
int ClearStack(Stack &S)
k }.J%Vu FGN3m,[ {C8aL.Z8g
    S.top=S.base;
Y;^g)Rx5py     return 0;3g(zm Z_,]~$K
}
/TY5?K-aL8S
a1b4LOo`]rc int GetTop(Stack S,SNode &e)[&CF2w[R@&J5k
{f `F-h!u-Nfd
    if(S.top==S.base)
$q e'`hr3S6z     {
_"lK~6XC;~U         printf("栈以为空!");
y \Cq-Fm D         return -1;
Y*ulv%}-XDr     }:p+^,A Gy wQ)H Z
    e=*(S.top-1);
Se4mnd+V6Y     return 0;C$CpZ,e&m
}8[$|7_bZj
&\jS2|zc.GF"[u
int Push(Stack &S,SNode e)2vX2NRM$Zg/wOS;D
{
&x]'H3j6M D     if(S.top-S.base>=S.size)1M!An$L9R)`
    {m$N:d{iHk
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
@RojVn,p         if(S.base==NULL)9b&~ ~0Z#fQK Y
        {
^&R"rMW9vJ_             printf("动态分配内存失败!");
2n;[3h-`7wA)lGZ1K             return -1;Bt!V f AS2P)g
        }&o`3W*@EIt
        S.top=S.base+S.size;
^$X_G9K         S.size+=APPEND_SIZE;
w4O M9Z.b1@!I6{5C     }4M:dR%XC+e-_%^A@
    *S.top=e;
iZPb x0b0Q     S.top++;Y@LD A-|A;s5g
    return 0;z/D S1Y[T&K$D&W
}
9w7}({4y M
\-C#K L\;sC4U int Pop(Stack &S,SNode &e)e\3t,X8@E Q:K:z
{AM1_5T\r
    if(S.top==S.base)(MQ)e\z0su`Q
    {y;ujdwG3^A,L
        printf("栈为空!");
s7@Y T3Q}/p         return -1;`*eW$XJ
    }
~N-Lc6qv7N6B0d&cn     e=*(S.top-1);
+v"} T+iVb,VWO     S.top--;
*R_ Tt"Lx ^'w ONr     return 0;+h.qy ]4o%_vhf7F
}
!{mY ^;Mo :nP`%CW
char get_precede(char s,char c)
0t#v%N4Mnpx.j {&D'O0UwZ!A6_Qv
    switch(s)
7[3b5T4I;R2M     {
"vw)G-rU6f2x         case '+':                 
'{q0D^ucf(Q2Q         case '-':j U-c$i3XL*X
             if(c=='+'||c=='-')j]&|N1l5Rf
                 return '>';m4Tm]3x:R
             else if(c=='*'||c=='/')8U!UGC/Rai`
                 return '<';E^$zGUW%G2r%f
             else if(c=='(')uV N9{-PBS
                 return '<';
+AW#h3}7O,G              else if(c==')')~Bw!| bI)vV8}3_
                 return '>';
Sl wZ}%}H)rJ,hd              else
/\6G"[V.?x0F2C                  return '>';
%aD#s rv         case '*':c3tG M9aM1LD
        case '/': y3D*Ra M9egi
             if(c=='+'||c=='-')
Ry%rHc'yN C0E                  return '>';
2[![r%d?/I:O              else if(c=='*'||c=='/')
G9B6d"it                  return '>';L%s/txG;zs
             else if(c=='(')
Hr$c"aX G/Z                  return '<';NH0e4l[%\H
             else if(c==')')
{#aJ1hi v                  return '>';U{"gn!\fe
             else
[3DNs[p5\                  return '>';5n!y Zf _4D
        case '(':1vT u(V5_f?m
             if(c=='+'||c=='-')
q{#Ra NK6]0V                  return '<';
.W CA*].cem-[ d              else if(c=='*'||c=='/')
.q:WO$~-G9l:R                  return '<';8C7G7{J$^2YvhY
             else if(c=='('):I*V*LE5KcW
                 return '<';C8p"_*NN&c0H+}n*s
             else if(c==')')
(tA4sT7f8d7c                  return '=';
's)Fl%Ih~!b,d"S]              else}2}\4EY/[1c6W
                 return 'E';OuDL%|!f
        case ')':wJ:[OX.sG
             if(c=='+'||c=='-')c'qzM$d b{3e
                 return '>';I#h#bo }(J8R
             else if(c=='*'||c=='/')
r C WP*s(x                  return '>';NsmAC:?e} l
             else if(c=='(')/H3\ oSk
                 return 'E';
+t,OC X,na)?              else if(c==')') p?j xyr!C/}E'_
                 return '>';d~ q+M? M i.@
             else"jS*y6];Sf,Q ?yT(c
                 return '>';-w.} TA |
        case '#':
S}i{V{+Z              if(c=='+'||c=='-')6v%q vE-^oL
                 return '<';
c)NR!ZZ'a]t$PX              else if(c=='*'||c=='/')
gT:H]fMl+s                  return '<'; r2lwT |yXF ?:N
             else if(c=='(')
NurK3D.^                  return '<';
4`E:{)U+]hiH D              else if(c==')')
)y]0X }4Js,e3L                  return 'E';
:I*ANsm4_,G^9a%\8H              elsel^`%z(VMCC
                 return '=';@ `mDCK7Q
        default:
?,C`*O3v C N9Pu Y              break;
!AB_)b;EP a i     }
!D#x)d/R(T#o(k8F3L[     return 0;   
?R a bG y$o*Ke1@9K }
?h%g u+bLs:r P1xg p2Us6K{C
int isOpr(char c) },Zk3_6p[$a/j7T }
{
"[I5n$Tk5t c M2D5Ny     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')w [y#OP!^/H
        return 0; e;xGA(ZVp+C!F
    else
3b(q#Br qA         return 1;
&yYu}m)I;Bfr }2g`g2`9wY ?Q

l%K mo} float operate(float x, char opr, float y)
/}iAS,}BPY:B {
\-~1Q:H0`)u0]     float result;
B$E pRx9O!Y     switch (opr)ny&S:_"F dd%N;@%{
    {
/[b7g EM]         case '+':
.e1D!^+q8k6N%Z h&R*z              result = x + y;
O3b6j[ Pp5{(QuM0j              break;cop$`r0q;j
        case '-': b&J.?(mz e
             result = x - y;G8o0iT*fMT-D,s
             break;
\I]0]|(n,M Td         case '*': %?;Yg Kv0\'\v!dkl
             result = x * y;
-OH(I8H|C1b Hu)L              break;
X DI W7Lwv8m         case '/':
KF1Qt-Tq*V0N              if (y == 0)e e{1n$v5_
             {
T]@'}'}0a*?/X                 printf("Divided by zero!\n");.qk,yC{`$s)Q
                return 0;
Ux.aU{8oKN UZ#bV~              }
a z1K;|!W:Q'n ~\J              else
5Zk'k;D k-TG{7{&T              {
m Ut}i[)o                  result = x / y;${7`V{$V%x {#C
                 break;,A0V a'x L2rZP fM
             }
%Pq7?yclf        default:
!y5t&]d0Z              printf("Bad Input.\n");
s D;B'p;\x$u(Z#CIV              return 0;2\.t?pJXH^`7E
    }i5`{l5rD
    return result;
b0z|sNv }    b GbowAl
.rK[]*`RE~
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
&Y{ wc C*RtGb {
C1k'Sy9s     Stack optr,opnd;1GHB?(h!`2w
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;^ cExk+{lMa
    char c;:g wm!s:N vc5Q:F'_9c
    char buf[16]; | ~2]"w,~R[
    int i=0;
sp Rh;si$]8i I    
y5db a8l J%B cW     InitStack(optr); /*用于寄存运算符*/
+r*n.blJN3cnmv&x     InitStack(opnd); /*用于寄存操作数和计算结果*/&Z3i PeL"I
    memset(buf,0,sizeof(buf));!u+wj-SUA1|2O1u
    %J1y/^'dAI!wE
    printf("Enter your expression:");
u;IBq;t8XxO         !J SU.uH(aw q
    opr_in.ch='#';@#M3T n `u6Ra3`
    Push(optr,opr_in); /*'#'入栈*/
j2c4H XN6_e J r     GetTop(optr,opr_top); W(LEk)R,~%d%Zo4?
    c=getchar();m Vu ~s(W!P^
    while(c!='='||opr_top.ch!='#') AFre-|\
    {zel+Ne*R(s
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
U{Zh Si         {2c'tb$E D8P
            buf[i]=c;7KD4e8`.x*?4JY
            i++;
P Q'da9P;la$i F!\             c=getchar();4ol9mQ5Oc
        }(IH0O\+D
        else /*是运算符*/|~CLWlT
        {
s%W`;a(E+Xl [6_E             buf[i]='\0';8StfP*KMf o^r1A&_
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
c/oD+j*L4Y\             {0@:G%Q)X+T!t&M
                 opn_in.data=(float)atof(buf);0FE6hr+Gn
                 Push(opnd,opn_in);
m9v6w`t ql1vk                  printf("opnd入栈:[%f]\n",opn_in.data);
G7`pC9k Cqt                  i=0;
(b&y7[5\s                  memset(buf,0,sizeof(buf));
;o I$z;o{ xq8V6IW             }
I ?t1r#]e5s             opr_in.ch=c;
+l%ly `Qi q_6d             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
?M?)@ Z8Wg?5~5c5~B             {PB!L"v~
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
5_u){['U{                      Push(optr,opr_in);t j9|&E,m*pd
                     printf("optr入栈:[%c]\n",opr_in.ch);W F5ee;J
                     c=getchar();
2rXZ7x(h)d\2Se                      break;~&i"L'|e
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/zC1QM n:C9V^e} V
                     Pop(optr,e);
x @1q RO#yaPR)i                      printf("optr出栈:去掉括号\n");PF;t]xXJk E J%q
                     c=getchar();
7eB;V~,D x[6s                      break;qMp;mu-n}~y)p
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ |Q$_svz
                     Pop(optr,opr_t);
;P3cS%L@l*d                      printf("optr出栈:[%c]\n",opr_t.ch);
Q^nd&h,B5L                      if(Pop(opnd,b)<0)
KjD(N'bfj I q(T                      {
Mx"ob7\'GYm~x4Q                          printf("Bad Input!\n");
)kN:Z@#Y\ d                          fflush(stdin);
VQ2j}+D(N0J                          return -1;BI&Gp6D yG-nu#K
                     }"B2h{e'x ? h
                     printf("opnd出栈:[%f]\n",b.data);
'a _g+qO%m5S                      if(Pop(opnd,a)<0) dL a [iVH
                     {
wfU'j#o }/A                          printf("Bad Input!\n");'VB+Z Aj4WV m
                         fflush(stdin);:X]3|j V$p3E
                         return -1;
&t4d2MsD R] ?y1`#kC                      }r }c |H:Tg8I'T6E
                     printf("opnd出栈:[%f]\n",a.data);
8h;A5r,~k                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/Q+N(Q,_ VZ\
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/;w)bQ ~v8zWn
                     printf("结果入栈:[%f]\n",opn_tmp.data);
`h3w D9m} IW0m                      break;
8r1S~T8P             }XO%Idt2l
        }
1BmWu2s#_sas+K         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
$s ](Qc LU\(?0xP?/p     }&z%C-\ Hy"{@
    GetTop(opnd,opn_tmp);&NvpL/y3iz
    DestroyStack(optr);5k C0vq#ZM"W
    DestroyStack(opnd);"M9o)`:dv0TE6e
    return opn_tmp.data;
'pN4Hc6}p }awa9o._ O
xl3F0p}7cc-W
char *killzero(char *res,float result)
hnLj+vg {
rd k6Bz-J;H1c;h6nJ     int i;
-] u x FF4v;bu o'QW|(F+p1U
    sprintf(res,"%f",result);)Zte/S4y1P%{j+YB
    i=(int)strlen(res)-1;a0|t^;~#F2|Q
    while(i&&res[i]=='0')/p-gS)nw Y
    {
~ Ov/x!l+b;m&x         res[i]='\0';(g~1H|3[P
        i--;gW%b.Ib1D~BY
    }"p%e.ZgW q]
    if(res[i]=='.')Th~7Qut/\y
        res[i]='\0';$u']|5o;n#K
    return res;ob-BE6wZo!i4]a
}cT"FnyM2N]U{2b
F}]z(ly
int main()
7r0T8WK5\~;r3a ED {4F4z#ms|O*P*`
    char ch; K2N~OaXP:O
    char res[64];Wu(_d&P$WjB1P;E zz1h
    float result;pF)@bB+?#}
    while(1)vh/c7dg(}$n!htd-]
    {'I!A:jwU
        result=compute();NpyAxe
        printf("\nThe result is:%s\n",killzero(res,result));
c.@D5[Zp^         printf("Do you want to continue(y/n)?:") ;
}|"Q$Zy         ch=getch();
(LpwQ1i[f5y9Q         putchar(ch);
1J.[!\;nT Bm)\         if(ch=='n'||ch=='N')] V!O*Y0q4vs
            break;+l8Or P^w[
        else6\-z5z&Ot:CN:t*a
            system("cls");
+D/Ob p,g jz     }-O4KYxW
    return 0;-l%H Jw-y)xH4AK
}[/i][/i][/i][/i][/i][/i]
i~s6v oi
\.Z/z y!PW [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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