捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
i,VI)I*V$`r 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
g_O0h:s+T1@f /**************表达式计算器************/
9vQkmKF%T_k #include <stdio.h>,Q-s-t4T;`3lm7X
#include <stdlib.h> h`}1C"k#L
#include <string.h> v(X1OJRj
#include <conio.h>!g*u5P1\+?
#include <malloc.h>
c;Hg4g [Z wP5uS'c
#define STACK_SIZE 100,C0Xs,QA@J2Aj
#define APPEND_SIZE 10
qa.cH,r B7f\f Z_!J,^A*`hgA]
struct SNode{
/Q0D f"w%?Q C     float data; /*存放操作数或者计算结果*/e B`zE4Z;p%k8K
    char ch; /*存放运算符*/]%]\!Rw
};
$[LK.n/HY9` 6X!y,dcu9Vv
struct Stack{e~pO/kD*U5R
    SNode *top;
x RH^9Y#}0Fx8@     SNode *base;
1a_D,q0M g;d     int size;
3o!gsMiR6?Sd };?j K_.{"rkc0GJQ
9_zvQ3d\1TM
/*栈操作函数*/
k Rz;Gah2x8[t-p int InitStack(Stack &S); /*创建栈*/1R.}*z.[(\9H#H4@&y \
int DestroyStack(Stack &S); /*销毁栈*/
p xWl [f5W int ClearStack(Stack &S); /*清空栈*/\)gZ:u2UO
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
6?7mY,`"?g*j int Push(Stack &S,SNode e); /*将结点e压入栈*/
-V3z_%R s"_6Q;_8] int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/,j\R2V.VU
[8DTx$C LP8W#k-a4@
/*表达式计算器相关函数*/&`tWE2j.I!e&m I)H
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
(mC0GT%R%Z'T int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
i Y y0U2Z"yS{ }|(@ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
\h6^ G-lk;[ float compute(); /*表达式结算器主函数*/ W*@ H/JU^7B
char *killzero(float result); /*去掉结果后面的0*/
+a+mLE7F I"sp1Ii5F cB/P{ m7X#K[
int InitStack(Stack &S).M/}W`JK%K#iPxV
{3F:s Z%jn"R
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));|#e#@@4u0`
    if(S.base==NULL) c5L}Q/YZ(YBj
    {
-D1c&Bt G x9K6d-~         printf("动态分配内存失败!"); [f+P&Pt8~B0J3`a
        return -1;$z{}_6g,Q^P
    }
5j)B*W [+s*b     S.top=S.base; ZHQS"]!jE jV
    S.size=STACK_SIZE;
-X(V/DU.T     return 0;
vc5jug }
DH~(F'^9v"V qd*Ge5I$Nl
int DestroyStack(Stack &S)
+t F#{,YH;d {
%Qs^/r|y^-c     free(S.base);];DUYQ5Xx:vv
    return 0;9D9gj/ZI7U9aP6gno
},EhEBW"@

})R)w-B,wC int ClearStack(Stack &S)
_ Y:p:dlu3|G {
D&P5|$s6|6e,{f     S.top=S.base;
/x(A0|$A M)Gq     return 0;
j4n.@2yVq.j }
S#|\)b NzWg [ O]bw%Hy'}:Y
int GetTop(Stack S,SNode &e)
6@)aLgI{&I {
$Q S-X)W6L%a\y     if(S.top==S.base)
"vPe*ww3x     {
5J.E#Q9r_ @}1?z         printf("栈以为空!"); HKG%C-|4U+US0b
        return -1;R^$A-@,](`6v!eY&ad
    }4j0I c+S7_%qhc
    e=*(S.top-1);
pB4e^5J b i;j7C     return 0;
1?*K-P3Z-cD[*O }vc.`1{i G8p
e:C#O&PB'm7q-K;m
int Push(Stack &S,SNode e)
6X7fC_)eiY8y"F {
(Y*^9YC Y C?1C;\9_:Ok     if(S.top-S.base>=S.size)
J8e7\-UCb i     {
9L(owQ7WF(y         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
zi$z Tx3H.|-y)jX         if(S.base==NULL)\ooN+?.~
        {
/N}m+Y:LC             printf("动态分配内存失败!");
&yr2P Wv             return -1;
i7x'sNFUv`e         }
[3S(n8e3Lv#] t6|Z         S.top=S.base+S.size;
+~U9yAiNu/`!A         S.size+=APPEND_SIZE;
1IB"Z |s     }
+}g~/}T     *S.top=e;X Mf_L9I2n
    S.top++; H_{'yK eI2PV*h
    return 0;H3\4H7N tw'w6^0my
}
wG&_S;j`.wP@;B @u|@_M*O(sU
int Pop(Stack &S,SNode &e) _6V^6u6{'j
{$mz9ndG3@'CMN
    if(S.top==S.base)
3y(a9s(M/km'M E     {&a"bHSd%r'I
        printf("栈为空!");/M B%K+y ? u
        return -1;
f%]oCT     }
0Do!m]L@d:})[     e=*(S.top-1);
+]!}Fk q{ \9wzm/E9G     S.top--;.\ kQa6u-~-z*EY
    return 0;x/lg2|2H%P6QM
}
+A#iCGQ6Z&N9S3@'E G[r|KGV
char get_precede(char s,char c)"q [%IT:n"`5J
{1T*O2|ZY C
    switch(s)
7XwtP@P     {
8qlv^8?1LQ         case '+':                 6J Y4r3\;\0VN9l&U
        case '-':
bF"t2L$v B2w Xm              if(c=='+'||c=='-')
AiCvW&a4A%yK                  return '>';
,foe!so0^              else if(c=='*'||c=='/')5n,vwJ"S&Q
                 return '<';
\8{7~%Yr6Z&s              else if(c=='(') P.rn M.Q#f as
                 return '<';
.Ek'}"kZ7S+a[ dA              else if(c==')') k|+@1ns k/[,B#z"a
                 return '>';
:h.O^OR;Iq7bh              else
TX iS:^pa                  return '>';
'KU+`7wv         case '*':C2}iNZYG
        case '/':#[ { F?.Y].t
             if(c=='+'||c=='-')
vej&y*D*U5y(h                  return '>';
#I F.D$X{qrf              else if(c=='*'||c=='/')'MI&m2n@2m6CF
                 return '>';
E H z/o3t              else if(c=='(')a:Sk7P-z:`b
                 return '<';.n;ai4LE mU)R
             else if(c==')')$E']]'YqF[1B5Xf
                 return '>';)qhY"?2{Q$e h~
             else
.uCBe8E{2X                  return '>';l Y\)d&R*]2d.{({$?I
        case '(':
!u.n-QMU}?g ZB6y1D              if(c=='+'||c=='-')
poJIKkv!R*\b/{                  return '<';
,g(`Q:wo H YD \              else if(c=='*'||c=='/')
9x){b*Y"s.S!DXB                  return '<';uY!ge,q#X
             else if(c=='(') lY"yFAG
                 return '<';
0T;F1^tI ~rN              else if(c==')')
SC:C(AEt&F^1s                  return '=';L j2p&Vm&\ V
             else'@fG2I#w_,WU
                 return 'E';
N!n3c-e~ d2m4t\5Cv         case ')':'l Z kFi6N;Z
             if(c=='+'||c=='-')p t o}:e9eE'Y[
                 return '>';Sb a"YgVK(\
             else if(c=='*'||c=='/')| b%f K7j\~
                 return '>';
NG.U#^%^X`              else if(c=='(')+b9S{RR
                 return 'E'; L4PJ7xX
             else if(c==')')4]Ej!B V~7l U$yE2R
                 return '>';|)yp8xoU,JK
             else
Zk.eB9C0{+D:O;X                  return '>';D L0b$enZ:g4hi8] U
        case '#':Rkm6tLi
             if(c=='+'||c=='-')
-]m,K~}i%^glcN                  return '<';^~#B&MuO
             else if(c=='*'||c=='/')J)E'f+BV#Kl B*S
                 return '<';
w-GR)t|~o'B)j              else if(c=='(')2X ^/Fl5c8F
                 return '<';
R Blp`X$U              else if(c==')')] Y[I*~{)p
                 return 'E'; Y$Z]$t._M|S
             else
@"s2G%H&Q2[/x H.p                  return '=';
8e{ }[$Z{0M4_;{         default:!h$ZpY!rH
             break; \?/kd ?Pk+V
    }
x"f0s)w`_ M2Lw     return 0;   
)|"U0|F&B6z pA;AB&u }5bC@oZlR{#A

tTEYG.@C kd int isOpr(char c)b$qP d'WL-yE)yB
{
d4~B6B ?     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
Mz,h p t6s?/D#U J}         return 0;*{,kJSg4c
    else
`r#Z7i.z1zJ         return 1;'J8x5a#Y,CW9?;W
}
u.Y,kD-gw[
Ru#r `!Z&tGn float operate(float x, char opr, float y)
5qux:HXXx_4l \ {#|*y4|s#a e r
    float result;D^@;L*~:K8YM
    switch (opr)
P.Y7r3AsjQ     {
0?A(N&s8^ ?         case '+':
O],M6j1en8z              result = x + y;)\3`7x? xoY%g)x
             break;9E4q] @/fB.w2}
        case '-':
+q4m-t)Nlu0Yw              result = x - y;:t6H;|H,}s*Hw0G(k@
             break;&Ph0ZK:h ?7D
        case '*': \H`d.V `/U
             result = x * y; g!Z;P \[/Yb
             break;
x6v[ Bm9_6Sc$oK;~)^         case '/':
:\/mpW}4R[(u!nm              if (y == 0)wi,y6x4`v-ur
             {Y#S'E2VEu|0ma:a
                printf("Divided by zero!\n");|q._ t W'LS}5q
                return 0;5oz7Q+t0V`g*M
             }ki^"L%{6{(b
             else
9Ip }!t0K9y              {
@8l9b ^ J7]8n                  result = x / y;
2IPH5^"L                  break;Y0S j5F^"g&Em
             }'R(N0qy3O&i9tJ j#U
       default:
lA4cD%u @ Q0^8o)e              printf("Bad Input.\n");
6pldOXL?              return 0;
.IZR-e7hG3`     }T2K?4\2fe
    return result;
%Lt1]@`u }    JC)E2q y^n

i,f*?/Nml float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/Cf/T"? b0k
{
P:b:q_&l }9db     Stack optr,opnd;
S7i&X!E^|2tZB1H     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
'tQ:Nh1~     char c;.GrN"Zy&k&^3g3{9I
    char buf[16];
u$@P*?,~     int i=0;u0f }r'|#KSc
   
J(F Yv{LcVIv$h     InitStack(optr); /*用于寄存运算符*/*me f'_D$K"B#B
    InitStack(opnd); /*用于寄存操作数和计算结果*/
Z3s/N fvqd     memset(buf,0,sizeof(buf));
U0fmn/xFO     iF |"Pa)xU%u}
    printf("Enter your expression:");
7`kxDk         $s-}RQ)ei
    opr_in.ch='#';pG pSf4X T+x
    Push(optr,opr_in); /*'#'入栈*/
d7o1j r?5{ Z Y;}.n)^5]     GetTop(optr,opr_top);
zv5\F+hx*k B\5Gi     c=getchar();
/c D a%H9?m0MO     while(c!='='||opr_top.ch!='#')
%b3Ol9SN     {A0TLu6D?1?)ogH/i$^
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
%F#B3X3[ e}D?(A         {aOJ+?2o
            buf[i]=c;
l"w"mH%IFX cm             i++;1aZa+e3M&VO
            c=getchar();
^0{1xt6o2]lD|         }
}9n0sHw!w         else /*是运算符*/
$h$_f$}1h lO"lv         {
FJqO S@*}_             buf[i]='\0';
C6ND-@p"C             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
] [4O ?U+`*P2le             {
$u[La5X                  opn_in.data=(float)atof(buf);X|lHr;`
                 Push(opnd,opn_in);
3c-e2LT3z%z1N&| Af#[-S                  printf("opnd入栈:[%f]\n",opn_in.data);
#t-d2_U3V/S                  i=0;oNfD i Ws:Z#@
                 memset(buf,0,sizeof(buf));
)],D4VW)E'IH             }0Z(_9xc A[A
            opr_in.ch=c;
H|0U m(K u]H             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ OG|l.S ~
            {-se0o\1CM&a
                case '<': /*优先级小于栈顶结点,则运算符入栈*/O c:_NM;\|:O
                     Push(optr,opr_in);[ l%|gd VHSX-[
                     printf("optr入栈:[%c]\n",opr_in.ch);)i FG%X|K F3m-o
                     c=getchar();
\$JE6kD%z!^` L                      break;
:\@7s.B0{0d3A h Xw2Q                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
,Q/dP&HG,nRIIWc ^                      Pop(optr,e);j5M_3uK)id
                     printf("optr出栈:去掉括号\n");
Wa0^oK?                      c=getchar();
Z8lP4D3J                      break;}d\.rGe's zT0v-t3m
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
fq#Q X;vW"j KGqxf                      Pop(optr,opr_t);
`XAe M4M7\ o                      printf("optr出栈:[%c]\n",opr_t.ch);
.d])m| `.~Nu                      if(Pop(opnd,b)<0)
h!w`+E{"^                      {
#sGU'i\N@ H                          printf("Bad Input!\n");W`x-dWi
                         fflush(stdin);
5i%WRO1?mt                          return -1;
^{7TA"J E@6M                      }
m7EM.He|8}$| b{ ~                      printf("opnd出栈:[%f]\n",b.data);g*c `]x9] E+z4h q
                     if(Pop(opnd,a)<0)
vpx)X)?B                      {`q0Ge g8@eQ
                         printf("Bad Input!\n");
6l {8A%t'^3H                          fflush(stdin);
W(Ca)O9n w9S2V:m                          return -1;.l%a zM^)k.tP'UL
                     })Ioo^4rU(Ei
                     printf("opnd出栈:[%f]\n",a.data);
:Yi H r4W)q!u                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
`$vv4n"Z'`                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
/\4ECT8Y{                      printf("结果入栈:[%f]\n",opn_tmp.data);Xe U-KM }(j\
                     break;:|cCy#^p] Y!i
            }5?%Q j@&i$]9_
        }
e6iHD H K$H         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
|.u+ZN*Zt1H     }
V2Z%CP%i-`(h5X     GetTop(opnd,opn_tmp);kb2R)Kdu/x
    DestroyStack(optr);@?~3L-L+V;}c
    DestroyStack(opnd);
Y6Xdi4m Bk     return opn_tmp.data;-Y9q+Etyu"oo
}
&i*a-dIJG$ckd T K _r.z s,v h6a d~3G0x0^
char *killzero(char *res,float result))sH4Go](k$u`P
{~4n nr%OG
    int i;
^^ w8x}1J(@H +HH4j.})v og T.w
    sprintf(res,"%f",result);4o5\ch-WP)N,n
    i=(int)strlen(res)-1;0Wf*Alf:p5c gL
    while(i&&res[i]=='0')"p;b n']/B4x(T
    {
c9v%g&D;f d         res[i]='\0';
_1h'WSA ~ ig K         i--;X:|7Ur}#zM U r y
    };g*r(eChY1o
    if(res[i]=='.')
dTfBffS8X         res[i]='\0';kb?N"vk_
    return res;(L8aTDa@,^Q(l1Ahu
}
y;KV7M%u6jn
Y_8O n%Sr k int main()l!KCg5V5^
{U,L5f!O;pI8A5Q
    char ch;-B@w}6h'[,L7L
    char res[64];
2W-q3i0y9`[     float result;5j!k/A+n+R,LiE6T
    while(1)+ZZAj7_%T n8G
    {
I^e@,]P6O0C h1`         result=compute();
'gi-e;t?UVN"r1Kj}         printf("\nThe result is:%s\n",killzero(res,result));n\(D6v&{sqHN
        printf("Do you want to continue(y/n)?:") ;
)D!C3v*Cz4E*c/p         ch=getch();?qTNz&{$w
        putchar(ch);
;w wT"U7m(T+lZF         if(ch=='n'||ch=='N')Bs1v+Qh
            break; n!ZBZ \.|7s
        else
&?zl'LR;F             system("cls");
t~$[zC1\     } Cm{ h/m C/w;]9d
    return 0;~n,]$rv d(@ G
}[/i][/i][/i][/i][/i][/i]
~P,f@ j*riZsEj$[ N%W)lI vZ)CF
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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