捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
o W3BRT k 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
CAdWu9O2T /**************表达式计算器************/6]qQ'z,t a
#include <stdio.h>"^#@:e7bZq(@d W"BJ
#include <stdlib.h>
`D"slHV #include <string.h>Gj6E(QIS
#include <conio.h>1u ySn\!rbs9W
#include <malloc.h>
"u]XgZ
J0tST8vYK9m V #define STACK_SIZE 100
!g%^*MgG;Z:x9m'P`N #define APPEND_SIZE 10
I VFbe'X!e
0u.`\ WmMM0d struct SNode{
!S[)R5HQmM     float data; /*存放操作数或者计算结果*/
z$u%IUe&WZ#R,H4t%Z     char ch; /*存放运算符*/
%p g J-w?m V2] };
j)Ed@Kf4J&}n r8{;b8_kJ
struct Stack{}CF9H!f quA
    SNode *top;
9r~ V/@ Kg1x/AjA&]     SNode *base;
8}Q(w\V"}&i     int size;m0R^5cPk
};
af&or]@y7y
9T;Hq_ \x /*栈操作函数*/R(r"B4T.G
int InitStack(Stack &S); /*创建栈*/Z` [ o+N.UJ2C.c
int DestroyStack(Stack &S); /*销毁栈*/
W^.L s8Gmb int ClearStack(Stack &S); /*清空栈*/3um,x(mQ*? @t&V
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/;Hh;Xuz+[*E(D(Er
int Push(Stack &S,SNode e); /*将结点e压入栈*/
+R)G x1M7o7ex int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/)J~r.X*W1h'V6}-dA

*Qu5X(BB(Z @8O /*表达式计算器相关函数*/8NI a8|xB6U+J S)xb
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
]2n/o2Q#r%L int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/9o)qdE]3|1O
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/G s:WD7B#w1pV
float compute(); /*表达式结算器主函数*/ FEQ$a \M/VI&_:?^
char *killzero(float result); /*去掉结果后面的0*/
*U'N~8k8p:Z/r 2T\S,a!t^-j I:}
int InitStack(Stack &S)"_g|9xFx,A$R
{
uluZI$Nx9g     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
&ynDSOM-BUCe     if(S.base==NULL)+S"j*A1MAp1Fj
    {%d C5Zt]G `
        printf("动态分配内存失败!");
?6`"g&lB         return -1;y J!N t[)@["L
    }
Cd'n9O9d.?     S.top=S.base;:PN-b/kWc}m
    S.size=STACK_SIZE;c!ZTQD*F
    return 0; w(Du m8n
}
$JsdC+Hn1WCP9[ k[ t8? S
int DestroyStack(Stack &S)_%Pt,n"Wsq.Z5}_Z
{,DEAK.[
    free(S.base);
s6L5\ e5A6if#O     return 0;Ss1D2Tp{
}
8RQ7I7u6N'dM sI:C .M${E [8SgW7~Rx\
int ClearStack(Stack &S)
"dH7o!kF'D3_C {
,jW6S`q4t8Uf3k     S.top=S.base;
k|F2F,?&Z;m     return 0;
Y fl9mS }l }5^NJ0U"A

(]/FYU` e"P#O ?%H int GetTop(Stack S,SNode &e)
/N$M x~8U e] {
|Fn/J,pI*\q     if(S.top==S.base)%{1O oq#u|+u#Ha
    {
4aR+W(R)Ec kW2zO         printf("栈以为空!");
:OCs-W2o$yF H*e         return -1;
N!v5wKMk     }
-I6OXy [     e=*(S.top-1);0jx`Db,EQ!dmz
    return 0;
c$W&Y+Q&W_ }%CB5C i'Ln;ab

xr U D!mnwd z"\ int Push(Stack &S,SNode e)7Au;T-@EU:a!@/A?
{ I2g,V4j$XBD8X `"Fy
    if(S.top-S.base>=S.size)
'i"{H$F&}e     {
{3\Ur\n.QO*P         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));2~a"U-ho Dy!?Q
        if(S.base==NULL)
hI o#WR8~ up         {tL p6ufAcuW2Z
            printf("动态分配内存失败!");+@6xp|N Q c*g
            return -1;4F5M^/[.zFd&yb2U5ixAl
        }6ct'AeUp"n-rR%`
        S.top=S.base+S.size;i1X&n"w7r
        S.size+=APPEND_SIZE;
W+t B C2b     }
Qw*|Yx+V;gs i     *S.top=e;
] C[T{H v3^9\^     S.top++;'ud bM.{ JZ&\&T:aA sd
    return 0;
H*b,G D*S%]%G*@ }4i#[9P)M+Y+`}nR

9h5V8K Bv(F,R4]E^!H-U(| int Pop(Stack &S,SNode &e)!Re:^8fLern
{
5o.pqi+y     if(S.top==S.base)R&m6h"Qdv}y:cpo
    {'y)@6H:NI7g
        printf("栈为空!");
G] D;wU/?^         return -1;!mBq0q| t3e'? u
    }q|;Q%g-w
    e=*(S.top-1);9P-w a/@2o
    S.top--;
@#E%FNZ v]     return 0; Q&LrG0pVmIe)a4S:W[3k
}
VGj M#O e n[&O_APQ
char get_precede(char s,char c)
4yS F4g o [8p {
'c3s3GE SS     switch(s)
a(vYO9O     {
_uba?         case '+':                 4jf%E@p^-L*\c;J
        case '-':CXD j(U]
             if(c=='+'||c=='-')
dgd9NM\.Dx9NF~                  return '>';
!uH0CU8o Wn'[6Kw              else if(c=='*'||c=='/')6I#I xfE!jE.Yg
                 return '<';#F^Y0~{[4p
             else if(c=='(')^3`)P[Nd
                 return '<';
5D MlB+f4F)@              else if(c==')')"qpj/x/[OQ+[RV?
                 return '>';
.gM `3P c;jP9Z              else i$@u,Wh g
                 return '>';
5u[kx lq(NG         case '*':4`*w%K8Gg1GZ{#f2I3Q
        case '/':
Cb$_]%r&a4t2Qg+kr;[              if(c=='+'||c=='-')
bI"o'p#Z2Q%|j                  return '>';
va!] pD.~4ah              else if(c=='*'||c=='/')4wkJ7u&L8`I2o"}4n
                 return '>';.iSO,n2f,p
             else if(c=='('):d6u#t:p}'_'go3]
                 return '<'; dAYk,|F Ya
             else if(c==')')vP\/q v4\ gG
                 return '>';
)PE!yvn1X-F/k9p              else
A O)yx$A/u                  return '>';
\%l#n4cE"O         case '(':G? R.t*Lk kO)J
             if(c=='+'||c=='-')2s0zN y%uV
                 return '<';
4n3B/~c$mJ              else if(c=='*'||c=='/') k3R._'~+zn9q;Q[
                 return '<';
d.G%[2Tqyf B3_q              else if(c=='(') ])|.M3tw
                 return '<';
:f Ty;W%TY M              else if(c==')')
^ b&G Nm"g r:i m                  return '=';
\a;ad|fv{.G              else
V;ai3`S7W9t}5hr                  return 'E';
"Qj2{.};PD         case ')': U'l(S S&nI
             if(c=='+'||c=='-')
7C:~,W'\ z                  return '>';
[ KO aUn0\              else if(c=='*'||c=='/')tk,N%`0VT#Fg
                 return '>';aei%@ Tc
             else if(c=='(')
7p.UXL fw)v0sR!m                  return 'E';
n ws&R ef3F#\&k              else if(c==')')
&U/}I3SY                  return '>';
d8Sv'y@'eS,@              else
%?-ps&M s3GH                  return '>';
P*f.Om r         case '#':8U8Gzt!w
             if(c=='+'||c=='-')3o4^{?#`1_p4N*p
                 return '<';|-` [-Sq@ N
             else if(c=='*'||c=='/') I9s)s'HeMS| j/uJ
                 return '<';
+Han_+c9K              else if(c=='(')1Z'a}v'GEGD
                 return '<';0~bd p)Ip:v+A;`B
             else if(c==')')
Fe8M7k_ ]'_m w[                  return 'E';
9X/d2h}5d!f;T              else
}y;q%|6S"T|                  return '=';g;iw5s&WC#b |$V
        default:
?2k Jmk%x              break;y}`!kI S2h%D7_
    }
d%`Po4X     return 0;    r3]IL!Fe`? l
}
I'f[*g H s3l3d8F:Q[r
int isOpr(char c)
`qj?)Z { {0V'U&GfEy
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')(i}TNo#p
        return 0;
}8pT"FJ     else
Sy,M2SO         return 1;
;E2^-C(R+dm't }
3g#N5b&M"oZ 0i6P!a9u,o AEa4x
float operate(float x, char opr, float y)
sN'ho}S {.Q_ O+AXvLv
    float result;
%E0k*b9q)UM!I+_9];r     switch (opr)!g/X2o'E$_m-py
    {
wP/nlX1Ef         case '+':
H:l-a I{A;A              result = x + y;;J!C;@:Vq|#|
             break;
Z `5{B"W8h         case '-': 0q7D-R;bu$u-no(jB
             result = x - y;
_"[%q(jx|3E%{8`              break;
o;o)]rT}3O4F d         case '*':
0`h0Qc$~'\+DT+fk              result = x * y;
,_}PvE              break;
2f'b8R/pw\/t%Z         case '/': #k"I,c&l4RD
             if (y == 0)
'L&X(N2cz~4L [MV              {1G6UD$|rsj1s3K
                printf("Divided by zero!\n");
Hh`8{yurwr                 return 0;M6^,eK2g
             }
\$b6m oE@c              else4X"Sr G'd
             {
6|)C[7S D%h{.k A6Wi {V                  result = x / y;M n?Sf*`Ee!V
                 break;?s&|RvxF:}kF?(E
             }
}E2P W9P1W!f        default: iv pn^:gj
             printf("Bad Input.\n");
b_9C5^\ Ox-@x              return 0;!j{9FNrNt
    }
QW;w"\w{-Yl'X     return result;:vU;| zB
}    s;|x(ur0~!B

,`7A ^S7xIy float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
9O/?&[O#s1joZ {
/G_5^x$r5|3mUt     Stack optr,opnd;
9S"E \7D l#l/e     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
4g i o1r9}6o$p1{\G     char c;8m8cv7]n8u#KO2]
    char buf[16];
6CD!mZp!AB c~     int i=0;k+RzC/tv'P#y
   
[B"p,b/h~t{     InitStack(optr); /*用于寄存运算符*/8n?xIG8~:]$vA
    InitStack(opnd); /*用于寄存操作数和计算结果*/ O1k!p4bZ3W-`)d'N%Q
    memset(buf,0,sizeof(buf));
$^XW)ZR\K    
M&fxud)k&{ ~     printf("Enter your expression:");W An*prH
        
9_r*x!x:SFD1hF     opr_in.ch='#';t;b&F0@h6?g2|;e
    Push(optr,opr_in); /*'#'入栈*/OlU/TR7pm
    GetTop(optr,opr_top);
.F4h#j*z)b~j     c=getchar();
Az&kI&I*}tD N     while(c!='='||opr_top.ch!='#')u R1n"YC+t uf
    {E$Zx2_ AGg
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
s;\Nc7M@+ZWm9f.H         {
;B.S*w'W%rI FV             buf[i]=c;
;R2Q [0{5~'bB             i++;
j6~6H$r/h             c=getchar();
D_ Q8B^2QJ:b/w         }
\M e'jo_F$ye         else /*是运算符*/T W*U?$G {Uo,VNI
        {] l^9M5w
            buf[i]='\0';f:|-^Eh&CAJCR
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/vE eO!_ |2^l'F B
            {
(_%]%W)H {!@                  opn_in.data=(float)atof(buf);
(~9fk`)CP.D](||_]                  Push(opnd,opn_in);
6Q,[+o(P)dg                  printf("opnd入栈:[%f]\n",opn_in.data);
]ZylG6M                  i=0;
an5s Rb                  memset(buf,0,sizeof(buf));
,k.Qk)t/Ij4c             }
?6na#O(ZIb             opr_in.ch=c;
@3A;W-z%`w             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
#~%DW?-jV#Q-k7b R             {v}#E9cmXr
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
q#Lo#KMj^ Yo^)]                      Push(optr,opr_in);
*O hM!vcB%W                      printf("optr入栈:[%c]\n",opr_in.ch);dg&UosMw C
                     c=getchar();,UXB&Jk6Fn
                     break;#Bc'}e$f,d-yK^"@
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
C!bHm;o+{IL+?                      Pop(optr,e);^Dp$H,ZX:~ Q
                     printf("optr出栈:去掉括号\n");
V$`(rbIHuJwW0q3c                      c=getchar();
1c0F^vi?'M                      break; u g K3}oa4yT
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/p]%LqT iL
                     Pop(optr,opr_t);
pq-d%FX5r]                      printf("optr出栈:[%c]\n",opr_t.ch);[ I%D?5m4w5CNFd
                     if(Pop(opnd,b)<0)
`}j4qn5I!CjiO+x                      {
UQyp:TX&x)y                          printf("Bad Input!\n"); vcD2}2JM
                         fflush(stdin);(a X-llW V.v
                         return -1;
c,h*R+S Z.|Cq                      }V}2MN([ ^vQ
                     printf("opnd出栈:[%f]\n",b.data);
`qU^~ g.I2y                      if(Pop(opnd,a)<0)%j,b~j;Y
                     {v5]I\7|A%d/N+s
                         printf("Bad Input!\n");
K;c$aB'y{5PZ]                          fflush(stdin);
9k9p:h\N] h                          return -1;y6ZC ~\5DWU]hr
                     })t1Tbkt8pY
                     printf("opnd出栈:[%f]\n",a.data);-V[(C C)ZH"]Z'NU
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
dECu7DO@7X~                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
x?a.z9q7\TugI                      printf("结果入栈:[%f]\n",opn_tmp.data);
tK8Qe,C:U)hmDn                      break;w NwPG9N)K:u
            }}h~,Hm1J+`LA
        }
6te!Rc8U P4`$Z         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
7Q0oZs-n$R8b     }#x7Z7gL9fU^`8x M p
    GetTop(opnd,opn_tmp); ~.J&yNH#H/g OB$fb
    DestroyStack(optr); h@0q9mN@L
    DestroyStack(opnd);
2q9RdSs*q&EY     return opn_tmp.data;0u/vf%EK
}%Wk5n8`0MsO%S|
e$~j(z*p
char *killzero(char *res,float result)
9OJn{O&G {l"}2s] ?LQ$\'Pa
    int i;!^8K2B,R$J&S i,Y
YR&kf&E
    sprintf(res,"%f",result);Gl6_tZ"i#T-E
    i=(int)strlen(res)-1;
9T_1Y_N6t.])x~     while(i&&res[i]=='0')dWKZ9S
    {
*b QS9\f){7C         res[i]='\0';
K5c] N|;K&N*P         i--;
1Zk:LSEn:iP2M'{!zb     }
\2^A$f!R^g3h0]?d*a     if(res[i]=='.')
1z nnC zt%M1]8k         res[i]='\0';
q:\-FLu(t-WK n     return res;
u(Hs.n&N }
'j3k(f I]0CK#Z :Ir x)x+Ck)?
int main()
O@6ojE0]S.{ K {
v1rrPv     char ch;^i*VW9LDIL-T;I
    char res[64];
:{;I+`a1ZVY[ g*O'n     float result;.~H'v$TP
    while(1)x7Xg0mm ib/A.Ra
    {D,G;]/x x$v)HB
        result=compute();?~@7i)D8l
        printf("\nThe result is:%s\n",killzero(res,result));5^V0I!B6Q
        printf("Do you want to continue(y/n)?:") ;
q-BB2d/z'W         ch=getch();
?4e&a3X+rd         putchar(ch); ~b Y[P'^7] |+i
        if(ch=='n'||ch=='N')
h#x*| \ yHq%G             break;
q[Kg-Vm,Rd         else
^"hUf m             system("cls");H)Z O#Z1hld3j$[
    };s%H AB8I
    return 0;
.iKDx/J }[/i][/i][/i][/i][/i][/i]PAM.E+G/h%r(h E.h

-d L d0k"i+Bx['v5b [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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