捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.K,sS*Mo5h A
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=8Oe!lOdJ
/**************表达式计算器************/t y!o?^+{
#include <stdio.h>
l5a-fw]c%@r` ] #include <stdlib.h>
JS\ u-h-W,{/vB #include <string.h>K jA9?UDY
#include <conio.h>
mkN7{gs6dQ/]6W #include <malloc.h>N's9f"oqQ E6x5[

gn+xb$@5U #define STACK_SIZE 100
n$fY&j.b ](Sd5[?u #define APPEND_SIZE 10
'xs M~u k$cW 0]F\ g-a)~~
struct SNode{
)b Ah4@#A     float data; /*存放操作数或者计算结果*/
:?8Z8fN1[RZ4Se     char ch; /*存放运算符*/
nE0yo:D]qYp };GM7@1e0I5G\
{oXi&T*@r hl
struct Stack{
m`Y8f#PmM,EM     SNode *top;#{ hO"o3EO
    SNode *base;
Jc$caa2J)Pjd1Se_     int size;
*a:@n:@{+]b gE }; R7vP+gOb
g3RQ;A q'ePW
/*栈操作函数*/&HV6x@bM
int InitStack(Stack &S); /*创建栈*/
:W9??)cN1L int DestroyStack(Stack &S); /*销毁栈*/
~+P$[s[)p)X)m\ int ClearStack(Stack &S); /*清空栈*/
mO2Ko F"r| int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/`Zkp%f?
int Push(Stack &S,SNode e); /*将结点e压入栈*/
3KbJg+f$P*h/QN int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
-I?+e#k-LvE0v
*p@ G7T8l#PG$Xg /*表达式计算器相关函数*/
,v h)I oa char get_precede(char s,char c); /*判断运算符s和c的优先级*/ oX m8g,n B y3jH?
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/!^!fcs4Q+E0t5`B
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
5z/]jM?$q float compute(); /*表达式结算器主函数*/
U ^^7{(z E$Y Tl7l'o*O char *killzero(float result); /*去掉结果后面的0*/ A"hzX\

*X)O8a1EnQE#E!P int InitStack(Stack &S)(F*sXe"u4x k%GP
{ y1p%ul` w-qX;M4A;\/I
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));n w#x w3v8k t+B y
    if(S.base==NULL)
&p/s8e\jz3k]*Pb     {0m6Q*`#xXR9s
        printf("动态分配内存失败!");C9d5Jy \xh2Dy8W-a
        return -1;
gMA1D9C/m'i?Y     }5TLDO1@ml7do
    S.top=S.base;uMq}ra
    S.size=STACK_SIZE;+Y'Y'PRF@"| {N
    return 0;
#O1zyuIzW }
q!_1xe"DZ)zs
'\;GvYc| int DestroyStack(Stack &S)3|BhLk2dd$sv
{9s @7~ gs
    free(S.base);
gL i"C0dC5B     return 0;
*z$Mq$P0Q9d0w;C }
\@+^`]t1~"`4h ;q&ux4h*X4s kl
int ClearStack(Stack &S)C-TGJ5Ai_6Y
{
f&_Sa;J|1_S     S.top=S.base;
+A,`yv'|2X+]5bG     return 0;-m8C[ F~c&N*j0KO1E
}
'z"Cl,M ~9P d
5Jxfvt int GetTop(Stack S,SNode &e)b}|^6B&C
{
|Q+}y:J*x Yv     if(S.top==S.base)!M1B cq,dC ]5W
    {
9_g5hx8l;]*N|%N C         printf("栈以为空!");
Klx9_)~'g3d'S[\         return -1;
f_t3~Zr5DT     } k9u+I_+wr
    e=*(S.top-1);z8x kVC@i
    return 0;
E)g TGm%Q }(]4m/X SFd+^S~

;@ Y&S+Em}(p'm3E int Push(Stack &S,SNode e)
&O*W#i5|9N t(r,u {KD2O$[0G/B
    if(S.top-S.base>=S.size)wDP E$c5j k]1y}
    {i[ e0N5B/u;[I
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
~ g S%O MG o         if(S.base==NULL)/E!^!u F s&`Q:AM
        {
7mcE"V9H!f1w X             printf("动态分配内存失败!");L:g*bl X
            return -1; ]6_ v'X,~
        }
8o6]a%J6H&rC@         S.top=S.base+S.size;
D&Iye8h"z7?         S.size+=APPEND_SIZE;
+x.X8\-^P!h'P     } m;^ PEF)T#d
    *S.top=e;+{d,vR]
    S.top++;
^kX7Tx px%[!p     return 0;&kF0xg3a*H
}1oY@9B-M
,ci6iD-}j:r$?
int Pop(Stack &S,SNode &e)
*Q'~ur|'t {ic7s9Ea5a6LU
    if(S.top==S.base)r(QT h{!T
    {
i+vv g1]l|@#~\7K         printf("栈为空!");:SO3v)@]"T
        return -1;:A\P `^!t ikRuz
    }
+K"}.U_#Y b&b#q     e=*(S.top-1);
!kEM5MB     S.top--;
i!j&HwD"I `d     return 0;
9jfS2A{#p$E'dpS }h7w`5ZdZ
UQ,GR!Q
char get_precede(char s,char c) N7uW} I CLP$B
{
wN N k4U+FT     switch(s)
d"r/y(g)to     {
!gk)cY(P7J4yMp         case '+':                 
n8[D`![5~v$R         case '-':
'|3k U.b+uhQ$c8~              if(c=='+'||c=='-')[%h3}1q6_x&t3x[
                 return '>';6P`~ | r4|D
             else if(c=='*'||c=='/')7t/O&Q%I sx&~y
                 return '<'; H |}V*s/Qb![
             else if(c=='(')4P jT!?p)x+G#|
                 return '<';
0_*IU:U{s              else if(c==')')
B)M*@*POG8T*q                  return '>';HN_(\B%E'J0m p8E
             else
l6Y1OQX                  return '>';
;~.wd SWNo]/u:K         case '*':
AIE-? C*iD6WJM         case '/':j| C3mQ:A`
             if(c=='+'||c=='-')
,C)Y/]&W+GA/~_4G                  return '>';;ZWt2f/a)]9y L3Ry_+Z
             else if(c=='*'||c=='/')
8r{5Y#[HHk                  return '>';
PR(_ ~2t:ia1F+Y              else if(c=='(')
$h3\4n{A [?#{1x                  return '<';jQ-HW&klH'e
             else if(c==')')
@RX:y/F                  return '>';
B;HQ+Z,j;Zc\+D              else$]|&[S:XS4J B
                 return '>';9HQTJE%b/@*N
        case '(':
-rM(P$oMU              if(c=='+'||c=='-')
Z.E\q7t8t                  return '<'; H#Cg5W?
             else if(c=='*'||c=='/')
H;aqVHN Bo U                  return '<';hDhKQ4V O E
             else if(c=='(') mVtxX+p6~
                 return '<';Df,w{2D
             else if(c==')')
:`n:g7v |v:t;E                  return '='; a [)t-}Z
             elsel*b%?dLP,z[
                 return 'E';
0}&u d'J1pD         case ')':2XR*^I LF DU
             if(c=='+'||c=='-')
%D8e)iPAy                  return '>';
`\)peG \$Q$G              else if(c=='*'||c=='/')r.BM5ZC
                 return '>';
o4vgIL a Rs              else if(c=='(')
h a!M[*xl*{0~                  return 'E';8~^ {@O'Y H2p(_)A
             else if(c==')')
n{4@uL,DY#Vu'v                  return '>';
'c2BydX M2@              elseqp T3E`Fo%~
                 return '>';
iIpsH!_ ~         case '#':&d*m$f Te,G$rc
             if(c=='+'||c=='-')sBZs,sd:T
                 return '<';
6F pK |+G?2C              else if(c=='*'||c=='/')
au(tK+d                  return '<';
L6J&@ uH?Y]              else if(c=='(')
P)BW Pw.D"fjPM                  return '<';
+m9^&j@9N|I3YNB              else if(c==')')A&WO4dQm&[
                 return 'E';;XYrP0h9NL2u
             elsekP r ryM%Z
                 return '=';+\q{ i1r'c,l!w
        default:`b7`#B0q2s@ gf
             break;
Qv4\ Ch6Mi c     }
0QA2k3Z~XH     return 0;   
,g)}W3x6Hh3B9N9s4]]8{ }
#tmf;KCNgD U#m5M (wP zb)GV)F
int isOpr(char c)
/L g6?.AO&o1r3~ {
K$p P%k y(zUA O     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
F'~]}#xb+G[+b1U         return 0;GKU_1v!BT
    else
I/d e m%t         return 1; H9ezY%@!E W9U \ F+r^
}{/AQq%U&r'vx
1Q4n$Z ~/Dj
float operate(float x, char opr, float y).| h.GdP
{$R.t3Y&DY%`0PT
    float result;'pV{zA8g)X
    switch (opr)
ax*T K7t2k\ Ayh@     {5tj6^0B5t&?'n
        case '+':
h{I9Y Z4oSl4E              result = x + y;AwF0e K:G
             break;
dN4{,K*d_ S*CXda         case '-':
H1QxR^"u,Mc              result = x - y;
.JF"qwZJ ?x              break;-p7RLs]+O%`,h:So
        case '*': t iz+}[2P:x:^&_
             result = x * y;
_ F/`(A.~6r7r@6O              break;9mt;Vwl6u%{X v
        case '/':
&R/a7G2af3W@.EU              if (y == 0)
@vyQ{zbz*~{              {%l\%O M?1e
                printf("Divided by zero!\n");
m.W)Z[o*f c!f                 return 0;
7_$~ H#F?%P&Z              }
(Vxty o/Rq              elseI#jhf4i
             { i2c)uK!F2u@p
                 result = x / y;
/w8wiR8l                  break;C mf.U}.^H P
             }6k/g ?+lZ3aE-E,V
       default: SaR'Hl5a _FI
             printf("Bad Input.\n");
5g.|)Z$o b              return 0;aat#R~R;YjX#iw
    }
ys? d2}A\!yg     return result;
eO6H!S]g*s(h }    %}%v(\%_a%Y3HG
7M _y*?'CcoYS
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/`%^[(XXrs8N
{"`r}&ja?8r}
    Stack optr,opnd;O0PHvWN8G4PP
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;BMS%z7W FP,PC$r
    char c;;HO#rH{5Q\(a
    char buf[16];
YTRnA     int i=0;`D]4V!}$\M
   
w?\j4F'^     InitStack(optr); /*用于寄存运算符*/
VOGn*q,c(V;lm{     InitStack(opnd); /*用于寄存操作数和计算结果*/-dEge)p
    memset(buf,0,sizeof(buf));e!fy@Ul
   
&~A n;u I%i"c     printf("Enter your expression:");
%u1e`xY5Z%v         &wZ FKZ6x$Hv
    opr_in.ch='#';
^.P^/|)W ~     Push(optr,opr_in); /*'#'入栈*/;KBha8e7u5P,J[
    GetTop(optr,opr_top); vbf ZFJ\ j%l
    c=getchar();
mT5H V8w!b{     while(c!='='||opr_top.ch!='#')
4Y'tt Mk i5{     {n+d%CE4SI9s/Q2|
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/]Ut y2K3~S;@GR S*I
        {i(k*obW\['t
            buf[i]=c;%R!}wd}
            i++;
H:Y f[2z vo0y c             c=getchar();
;gD-JiCo;y         }
L G$`'Y*r;`~         else /*是运算符*/
j/y9b]8T V+t;|:J         {XJ:vk0t)F
            buf[i]='\0';
SY3B)u~:I%e             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/&l)u2wC/L]t
            {
)FR vv)cO                  opn_in.data=(float)atof(buf);ky4EX+qt&[
                 Push(opnd,opn_in);8vLy6GV s hr
                 printf("opnd入栈:[%f]\n",opn_in.data);9[xe$iu)V
                 i=0;%k)tu6mA n$@
                 memset(buf,0,sizeof(buf));
A{]v5^p             }E-z.\;SQ S`_w(Md@
            opr_in.ch=c;!c!? O]o$G7s^JL
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/;`5`4~P~5H.uUH5QU
            {
9WE}bP-mq                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
3z@h5TT-N0Y0E                      Push(optr,opr_in);
T f `fb                      printf("optr入栈:[%c]\n",opr_in.ch);
[k7eQ9n+|5E6t\ IY                      c=getchar();2nY"@6hJ [Y$_
                     break;
#y CeC D(I z["u                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
j0]M9w4`/K                      Pop(optr,e);$P d;r;s)[l.F8Kg
                     printf("optr出栈:去掉括号\n");
,[)K4lc!B2kTO                      c=getchar();JQj(W~0~[5x
                     break;
;Yi4[O!|5H^!pi                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
:d o?LD` bN                      Pop(optr,opr_t);9K,~"R%O8J
                     printf("optr出栈:[%c]\n",opr_t.ch);~Qj{;Cy.C
                     if(Pop(opnd,b)<0)
7P1Vx Lb/Y-E                      {
X? J-~5}RZ                          printf("Bad Input!\n");x!s(c5ONRU
                         fflush(stdin); y'Qa'n"mL
                         return -1;2Fv_6Wrf,u~
                     }
O^i,B_)s F h(t                      printf("opnd出栈:[%f]\n",b.data);Vu.E(~s2{ I5EK'L
                     if(Pop(opnd,a)<0)
(p+Q3J sF5J                      {
x9t8t.V&_s\4pf(F                          printf("Bad Input!\n");/Z8rK3~a/L+L
                         fflush(stdin);p0f7l7glP4@'YA"v
                         return -1;.Zre g1az4\0W%q%c
                     }? o+Uj'm
                     printf("opnd出栈:[%f]\n",a.data);!A/L zm r&_6F
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/l ? ox$fy\
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/;MZ~B6Q}L o
                     printf("结果入栈:[%f]\n",opn_tmp.data);,g mp2Ix$W
                     break;
0d6r3Sb#qv*H             }
!E"OCw${s3M         }#Bv kmW/P#b_rM0z)v
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
$^5J;}Rl6Ta     };CMm ?3_U2Rkm'u9OhI
    GetTop(opnd,opn_tmp);:PF_`vB.@
    DestroyStack(optr);
W3?_O$?+^pA3m     DestroyStack(opnd);
;s2C oCZG#p     return opn_tmp.data;
-w#d7wfz:J A NxK }k n]qZ(N{
z5RU'IoI:i#{|4@'f
char *killzero(char *res,float result)
tH1@6@w{N op {
%D6s3k:sP A     int i;
7w-j1sf*R7k&|
P;dO{rbD,_     sprintf(res,"%f",result);
,k!]6wG+}TVMReL"_.h~     i=(int)strlen(res)-1;#R9@;v#\ vQ
    while(i&&res[i]=='0'){3QlwI e@D@m
    {R&v+E6N*Xt
        res[i]='\0';h(^M Xo&igV
        i--;}9flI$aC:V(gL
    }
?RiXSs     if(res[i]=='.')4c,h:B'w6{'C+C
        res[i]='\0'; q'Ulm0S'_ g
    return res;
8\dO2Q4? vU6v }][0Xq"KE7~
;_zipJY N e
int main()
Z8|QX0Q,cy6L {
y D/q7K9hC-UT     char ch;(k@$S%ey^!u
    char res[64];
2w(RV c%v5mEt-r a1H     float result;8^4u;e+UI
    while(1)
t{J u!A9l     {6w#I#ch#Tq9~m5CG
        result=compute(); R*vf!S`O-ep6r-Ka
        printf("\nThe result is:%s\n",killzero(res,result));
1p3n*n]Zg-v         printf("Do you want to continue(y/n)?:") ;
*W8h7paZnj+g         ch=getch();y ?YGJ6s t-M }ai
        putchar(ch);
dc kc,i9|         if(ch=='n'||ch=='N')
~f#Dq'i             break;o {S)\I&d
        else
H r mRS4DAq             system("cls");
%L7Dt9G"ru     }
c#z1R ]p8S s6gge     return 0;
5p[~owbT }[/i][/i][/i][/i][/i][/i]0oB$V#DoL` {
7L fGin
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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