捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.J"FKO[
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
;}6XDx{iG!b /**************表达式计算器************/
_ L z2~\%n #include <stdio.h>7q(W S3yv
#include <stdlib.h>
;m w[^P4H9yC4b #include <string.h>jY-mut4H NVV+I/YT
#include <conio.h>
;O3~}!\/T%N1y} #include <malloc.h>
(\-V.BA(`0| dN:p E_9fY](j2Oj4{
#define STACK_SIZE 100
"CCN6z7E kJ"M;P #define APPEND_SIZE 10
h$m7m5p'D@W n I5e2uo
q b(edI%D struct SNode{?;z{(Y%LN1i6]
    float data; /*存放操作数或者计算结果*/
i#L#aAuu-\-[#Psps     char ch; /*存放运算符*/5K5mu'S^ E!STx
};
z]9pB)Y8~%C/d *By4E0q^:b P2`
struct Stack{a|a4B+cD:Lw
    SNode *top;
7GX7X`6n0[)H     SNode *base;$q#T&R&},XET5e
    int size;^;W K{H+MRvL
};
?+d.k(\i!J2wnhH V!T?h8x)LP&aL
/*栈操作函数*/
7_Tn so P int InitStack(Stack &S); /*创建栈*/
!G Qz hM;[ int DestroyStack(Stack &S); /*销毁栈*/
mYH[qp int ClearStack(Stack &S); /*清空栈*/
#D vd4cB` jw X int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
b"Q&tr0]N int Push(Stack &S,SNode e); /*将结点e压入栈*/i Np6I*U2a
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+q'[}/k knv&WMc v8L/B%A7?]$d
/*表达式计算器相关函数*/
:Bl"g6o+V3@k char get_precede(char s,char c); /*判断运算符s和c的优先级*/|c dY7g+]q
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/:Ah6\ZR
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/:mCHN}0G.q3v
float compute(); /*表达式结算器主函数*/
xqe+Lq Rh char *killzero(float result); /*去掉结果后面的0*/ B slg6G;R9{'s

y3w S!M ~ ]?F int InitStack(Stack &S)]aL+L?.P6v
{
K5iD-]-n;f0x     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
?dM?7~     if(S.base==NULL)xlI@9uD1ty8d
    {3F&ag2K'd5a
        printf("动态分配内存失败!");
fht^l         return -1;#a"emL(gO+S#N&_4l
    }-| a(B$kb%T
    S.top=S.base;
l.`4z-IW Js     S.size=STACK_SIZE;
,N @ nX oa%ii     return 0;7a;b&LU*dKu9{
}
3d@!] ^5EI:u ^!mva0F&s
int DestroyStack(Stack &S)
i6G M;Xt:K {
'I5M I!Rn*b%ib     free(S.base);
kX)@-Y!@,u2X     return 0;
&FX o$jBb:dC H)B }
Fuu+^{$Or FY;[%H;B^(T#_
int ClearStack(Stack &S)
2i%m9gev#C#f+g8u {C.AN%M;Xs'L
    S.top=S.base;?6]s/OB:b*j9R*QSe
    return 0;
b vE O7\;\ }#Q1p;|k(c)kN0W
0?z-oz-Iz-FLr*E
int GetTop(Stack S,SNode &e)M_(`$x4\
{
j2T r2P4_Z     if(S.top==S.base)
,Wyh M*x     {] i_GC5bc
        printf("栈以为空!");
5E7l!O%mICSX         return -1;5g*_*p5IZKdZ Q
    }:Q*T0@g5L1B'E$~~
    e=*(S.top-1);
{.c;e"e~q!n     return 0;
r2j*h&C%_ }rt"Fj*x9h

$W%y:@)}EX_ int Push(Stack &S,SNode e)
V;esI9H/@ {
5d,H j+I W#h9c%ByS"a     if(S.top-S.base>=S.size)g&t[n;g1K
    {
G'aYWY*I o2v         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
H2D pu,n+{uYm         if(S.base==NULL)
9C1Qu P8g|Z2uV         {
,h[6bs7nK             printf("动态分配内存失败!");Ot n0zaV#uNB0D
            return -1;
,B!@+[6t!i d3^         }+B%N;g*FW9O5]
        S.top=S.base+S.size;&W7bH+z#C c8UJCKE
        S.size+=APPEND_SIZE;
z {-{kCV-@     }\MQ u;t.n
    *S.top=e; T _:G"D\x}2i^
    S.top++;
h*g5ms ?4[3oZ     return 0;7\3i:`#{ m
}
FJX ]'k ou
fh*Lg;u(f([k int Pop(Stack &S,SNode &e)
:K0L|%[g {4K;oCc/MuB
    if(S.top==S.base)+J'hddT2^u4@1Z
    {ZiNWe
        printf("栈为空!");$g!b5Q5le-u+M ne D
        return -1;G~7RH e|f(z
    }
Jyh.s }.z5~     e=*(S.top-1);
CmC9Cp"eq r J     S.top--;:z o oAX/K
    return 0;
W1y8t]U6SnR }
+G"Aj;PSl_
{2g+Sp$B? N2{$wf char get_precede(char s,char c)L5PQ[D
{
h6hrS u     switch(s)
ls_#f} p(v-H%m     {
+I1M l4Ugs;U#I         case '+':                 c9c!F*BE?x
        case '-':
E*dc"I$_/Wmq"B              if(c=='+'||c=='-')*I3r4[6X;Vf
                 return '>';"t@hVdr
             else if(c=='*'||c=='/')V fN}0l
                 return '<';
YT2Wr:[Z4x*|5LiD              else if(c=='(')
r!O.fqd:~                  return '<';
9U vt {d`*X*{              else if(c==')')
3C-U]t0_0f                  return '>';
!`t)t o cL%c,\l"VH              else #U9_I b&x~ s
                 return '>';_L!^es'Sk+b:C's]
        case '*':a8kv2q tKMBMF
        case '/':
4{u9us7ylj              if(c=='+'||c=='-')
#|-j,OY&Z                  return '>';0?pdt~6r X%sv'jq4w}
             else if(c=='*'||c=='/')
5C.bml;z                  return '>';T1W W"Q hSn
             else if(c=='(').]/pf ~7bz%n3NX+{
                 return '<';(kLU-GW;Qf~!E x
             else if(c==')')&u {9f+\6\2~0QO
                 return '>';gu.qW,G3a/S(z _ e0O~
             else%V }G&qAQ
                 return '>';
`3{ l+R [EI         case '(':
.q};Q}+|'FG              if(c=='+'||c=='-')g!AJ]6q_rd$]
                 return '<';fv%O-A)W'R9GE
             else if(c=='*'||c=='/')"C$O R&W.@rcW
                 return '<';/yu;m/h&j%w2e8]
             else if(c=='(')&D*GcYR!x,s'N
                 return '<';
#^+PBR'er^A              else if(c==')')
A0IvL.x HW+q                  return '=';
R-D$b/Y X              else"e2]1H+m _B+f
                 return 'E';ppf io[
        case ')':
#W#C3L r B              if(c=='+'||c=='-')QN4z(]j$lY2^;I n
                 return '>';\'b j+G(Z_(pF$~X
             else if(c=='*'||c=='/')
$jI*t)P(X0T%U                  return '>';iW1k$c:E(T$z
             else if(c=='(')
l"w1c:e _q^{3uc_C                  return 'E';
+kW FFddz T              else if(c==')')
0mMGD9z]                  return '>';
?I[4f)ob*`|X              else
p"Q\{zj                  return '>';
.m|8R.hk5S7_9y+}c         case '#':A"x A2pp2[jl
             if(c=='+'||c=='-')
`O,h7xG                  return '<';
z+]:~?vQ]              else if(c=='*'||c=='/'):e!Q4QzSw
                 return '<';4v_g9y/s-wf$h$V
             else if(c=='(')
qBu.[.hU z5hn _                  return '<';
-a0C1|T e C              else if(c==')') A*W"}LcX+jwpw
                 return 'E';
F"^K3^,_f(vO              elseKtGPG+\
                 return '=';:D;m:SL E7|kjO
        default:
5b?0h+R'x D(|J              break;)p@^6j_"{
    }
W6L0W n d]%u/e'M     return 0;    $nJ%l5M z.m
}7U(Bb3\9g}7w3U[L]
,Z Z(G6?@2N8}
int isOpr(char c)_0R2tS6_
{ [7n0e2t w:Az?-|;|J
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
-q@5@ K!rVIa         return 0;
S2}7A$ly)uU     else j |.N/_e;\U9sy
        return 1;2Q)^5U.A1lep&s'a(H3B/Y
}5i:SP%]2s
6h\%X'eL9t
float operate(float x, char opr, float y)
AFP4OYdA+t.zPr {b7K8}(jE0L
    float result;IW:To~o5n"J^
    switch (opr)
f5~4r};R1T4Z*yp     {
?S1f5[8h?         case '+':
!_Zh4s}s              result = x + y;3J~!e:f'BUH{D
             break;
5Y6?Jd+ZY         case '-':
k @-k)FPK-[F"N              result = x - y;Go:M4rQ YE^I\ {x
             break;gB ^Uk?Rrm-q7u5m
        case '*':
$p3n6K5Le              result = x * y;k*v`nGH4?4^-B w]
             break;J*ohGYd6[bm
        case '/': CJ arv5On^/J
             if (y == 0)1@BI%QOq0X
             {!j!b.[,K;D O)z
                printf("Divided by zero!\n");kB#S3h/MpHq
                return 0;
nw6`y l UL)b)[P/p P              }i$Tu'T(L8|C6UV+W2i:{
             else
qW.f,[O              {+|4o*S!|$j BLad'Z
                 result = x / y;
3Nl${b!ntY%d                  break;;r;I9_j&f'? lc ?
             } MbCC"D/W q*G
       default:
"xq`#E0UUI:|              printf("Bad Input.\n"); [ Ti3Y\6[)z&s Eh Z
             return 0;
b1d f@*_a     }
0F:Gm?"bv5s'c     return result;p]+_,x5j#P#C1o{w
}   
'g%K`l;d S rg
1eR{2`!H*L#D float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/9V~9Q:b0q"? y Iv3[
{9cY3w/D;T5^
    Stack optr,opnd; A(aup?v8vk*JM I
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5C,E:h&u3Xp-Z     char c;"F7DOl'?QSK
    char buf[16];WG_Q*J3]_
    int i=0;
9k LF!^M~     $}Q^ sX;A
    InitStack(optr); /*用于寄存运算符*/5m]S?,r
    InitStack(opnd); /*用于寄存操作数和计算结果*/1c/](K/y?H0x Qb+S
    memset(buf,0,sizeof(buf));
T;Q|/c2c    
l T,}d&[K0I6y     printf("Enter your expression:");b9d2U ZW
        
luIJ0u ~)n     opr_in.ch='#';KOd!U%i d*^
    Push(optr,opr_in); /*'#'入栈*/
{(B1B&apM.x|W1m     GetTop(optr,opr_top);
.{AN"y*XT     c=getchar(); [ H,^ m3| |(j ]D
    while(c!='='||opr_top.ch!='#')
"ea m;q7b0`wb*i     {^i;@LfI
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/Y4}f g-TP'r6}
        {C*LJB)c(n9OD
            buf[i]=c;
g)o9AmVQ8B|K             i++;uX D#eym7c
            c=getchar();
h:g`&}3U4IC         }f-s9Y:KR
        else /*是运算符*/
D0J{)_aB         {+VM+m7hy*pXp
            buf[i]='\0';1]D:M O P }
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/Q'[ h[[
            {)s{] G^f7R3B"Vm)J
                 opn_in.data=(float)atof(buf);Un9@/k T;[J-SLz^
                 Push(opnd,opn_in);m X$k`Y@'F
                 printf("opnd入栈:[%f]\n",opn_in.data);4]P \ Qy'v5\F'B
                 i=0;Q*^D7R h NVA
                 memset(buf,0,sizeof(buf));
h CC8yR&b9}             }
T4J8lH.v};_!t             opr_in.ch=c;
2pi N-Osih             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ DHBT2|IX
            {%s%GZsl'R`9g8E']
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
+C r.NZ J2\n                      Push(optr,opr_in);
}Mg5i(o)A Q4[2y                      printf("optr入栈:[%c]\n",opr_in.ch);
$~L/_:`,a7{\n                      c=getchar();
)vt klNw%N]`                      break;
n&ft,E_M7P(F                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
Uy cgAa                      Pop(optr,e);4[X%N;| JZ*nU(G,b6e:v
                     printf("optr出栈:去掉括号\n");S(`@ H{v4q
                     c=getchar();
b z J ?+ak1Jr([ [                      break;!RXs9\]E2V
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
j2e,y*z6y+Y-cxp`                      Pop(optr,opr_t);
v'znZ2Qn                      printf("optr出栈:[%c]\n",opr_t.ch); s5q'UYF Z n
                     if(Pop(opnd,b)<0))cp"q*i2}u
                     {
+BxIlVu                          printf("Bad Input!\n");
6?2H-`)c B r                          fflush(stdin);3L1}5l!S$P0Sq7n:}m
                         return -1;
|(U~9y%G5Vv2D                      }
nOD-?E;bi&J3M E                      printf("opnd出栈:[%f]\n",b.data);R'CnT:x H
                     if(Pop(opnd,a)<0)&@#z#hyW~f
                     { z#QS)Dz q8aU
                         printf("Bad Input!\n");6egF5?#P1{p
                         fflush(stdin);%k*`J$d,@H
                         return -1;
}KE-a8g0i}-P-|-a y                      } ^1[*DaoW%YS {
                     printf("opnd出栈:[%f]\n",a.data);
nGz#i^ ^                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
MNo)o W7CN`                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6PcF5})\w \'?#e                      printf("结果入栈:[%f]\n",opn_tmp.data);
2F7Zk{-H                      break;
(OG0L)\/^y{5F2p(?             }
9rK"n-j8F.C(G HN         }${7h cN0EUYbj
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                R4TTrX*v"Fzj
    } [ Q2K~wy Ma&[ P
    GetTop(opnd,opn_tmp);9UE3e[Q
    DestroyStack(optr);T3v#IWp,c!I8t P%V
    DestroyStack(opnd);
3f+Y!gu@:K#u     return opn_tmp.data;
Y'JG9n't RJ }
)bL$Mfb}1SE&D
y0N5N$o;^.?bN h char *killzero(char *res,float result)w3W3q:M3z}
{n0HfJ!^8D-eU9a
    int i;'b8`IwEc)|
.q"Ie6jjV#^
    sprintf(res,"%f",result); eBo6h7ux
    i=(int)strlen(res)-1;
9U2Y/yg k"}0?`]n     while(i&&res[i]=='0')h"zL+]5t%_)g"N
    {
&`u \$V ?vu         res[i]='\0'; \m!d@\bX"F`
        i--;S|r2Ky` B(g
    }#b,w7i&S:Pi@_4@A W
    if(res[i]=='.')
&u"Bb%^n%? J         res[i]='\0';XT9S9Y Fw~L
    return res;
6` p/lB&Dm }
Zk p7D Kuce +d#O~ }1?%}#X
int main()
'KV0b(S.fI9R {QhL?0ibh(rf
    char ch;&] r&d!p7sT.@2S
    char res[64];C5@0T5IHnb H0a
    float result;
H:l/z#H S     while(1)4V'n AFHi'J
    {
`F&r:y*z6g         result=compute();
%_B1u X F y+r/r2Z9iQ         printf("\nThe result is:%s\n",killzero(res,result));%eJ L^M{V:D0Q Vz o
        printf("Do you want to continue(y/n)?:") ;
Y;g"q-_:BC2V;ki         ch=getch();)zK&A5z"\a"s
        putchar(ch);#qYp/R0EuW_C
        if(ch=='n'||ch=='N')
muZ({4I1_5j:N             break;
!c Mc,\q         else,ECq&C l0IG'@9W
            system("cls");
'[Ud3j;S,cBo     }
F;~}%G a-\'s,|#q&e     return 0;
r0fw]he,K1S$AY[ }[/i][/i][/i][/i][/i][/i]
7D!F}n"Tm3xv
:wsT/NP,G [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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