捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.#Ug9S|t3\7s
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=gB5Bol!^YWc)ti
/**************表达式计算器************/5Z2y%nL6~
#include <stdio.h>3H Y _qs#di4e
#include <stdlib.h>%c/_Gee!d4S.SS+T
#include <string.h>&B-j"o"x[gzM2}
#include <conio.h>6z.N6WY(K F~v1a
#include <malloc.h>
$t0DN`uQ7G V*A-ms T&fp
#define STACK_SIZE 100
G]&?c4TR #define APPEND_SIZE 10#O+P/@u2E.I"N

r,d&S SumW struct SNode{
VW!R2RG2l7~"{     float data; /*存放操作数或者计算结果*/.E&AD E9eussXd
    char ch; /*存放运算符*/ r%X0cTn#k2X
};
,A3V P4Y EnQ
!Jj rqTDn] I7| struct Stack{
d0f%~Z4R0t     SNode *top;
0g9n5vY!dU1DG     SNode *base; O p#eT1Rbr/q
    int size;L n1oXx%B
};PaCt2z9R

&Z-?$s dyi@#wNH /*栈操作函数*/E/o4u&YT
int InitStack(Stack &S); /*创建栈*/x#^)@| u0Y*Ym(A
int DestroyStack(Stack &S); /*销毁栈*/u%l0g&A$va"p
int ClearStack(Stack &S); /*清空栈*/
&BP EA,p$Hr int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/yow,M7I4@ H$^
int Push(Stack &S,SNode e); /*将结点e压入栈*/eOk&`k2{n/[8j
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/7G x2~Ng:`9P+c{ f

WO'l_k0Q /*表达式计算器相关函数*/x%Hm8p v,Y}2e
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
!M!uS@^ n1f int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
.W9Evjr float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/)g!bv]T6A7Q
float compute(); /*表达式结算器主函数*/
g[O9x e ^GY%o char *killzero(float result); /*去掉结果后面的0*/ Se)Xm5@g"u

K9}*{!oC"dZ int InitStack(Stack &S)Vl5Id!bjP
{6_~&K4IvI'f?K c
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
~*[!dqXwPX     if(S.base==NULL)
![ B.V\,UQ,s     {
EG(J0s A@5C7lUA R         printf("动态分配内存失败!");V n ^ _VwES
        return -1;
T+D7a P]#e4gm3]t$Z     }(s$Mm,w+?Nu:a-y
    S.top=S.base;$] @0l!FpP
    S.size=STACK_SIZE;}|I~+C:b4K\uV
    return 0;
B7J^1Hy#w@ }
x$c7uV^yW
3?5d&}Mm/S RG6Sn Vw int DestroyStack(Stack &S)
4beR(?^9}K {
*s r TGeZ     free(S.base);
4jl%\-m-@"`#~     return 0;
1`z^%b [i];PEh\"|-R }N,}4c+V1cK
&]3I7f#o \x]p
int ClearStack(Stack &S)E1qi H0p c*Z\
{`xO VX,C|
    S.top=S.base;
] GttEyMhU     return 0;
uArpf }
NhjRZZ#}0i w~M P _
int GetTop(Stack S,SNode &e)
"QzjP*~/YY[Mg*K4A {
3J-]G*A?1}$PS4T4V5eO     if(S.top==S.base)
9yB-kJ/k2g     {;ftO he1Xw1w
        printf("栈以为空!");G?6e"d#h*M
        return -1;
rfJG@P lz^R     }
&[QVS#t     e=*(S.top-1);t(zzK#lXLK g
    return 0;
N#T]M-b.]S;m }
p[&ML+d
OOL.Q)|V)ywei wN int Push(Stack &S,SNode e)/N4d.Q)l/e+dr5^
{2J2{4e/YAF+\4g
    if(S.top-S.base>=S.size)
c3b0i? p?gh _`     { j YC k&Q E7e~9|+o;@
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
8I R;N#M6?         if(S.base==NULL)
3RI6rYg         {v3CBZ4c rO7]
            printf("动态分配内存失败!");
St4`-m&AK^ K             return -1;:wkZ FtWu
        }
g qWJ&h@8JK)RA8a         S.top=S.base+S.size;
;zg)n.e)]8Y2b4O         S.size+=APPEND_SIZE;k&k.|8p2V q$Q{
    }
)oTWe-If     *S.top=e;
Te$da(KM:KD     S.top++;
:tINi;~oN5N     return 0;
\jCa:wk }
k2PoT oy.{ OuxXp"?o$y-|
int Pop(Stack &S,SNode &e)
J9V4i?J5sr] {
5n~Nr!X.r@:X-M     if(S.top==S.base)
^ Cc+V{%qE     {2@m*~BP!hazn5v
        printf("栈为空!");jw8P&e b `(j ^0Ae0m
        return -1;1KstFPjG
    }
*@2XS7fiyv     e=*(S.top-1);&eom-Ke
    S.top--;,lM!RG#Z6DW sE
    return 0;
-IU&C4f'oAK$J } }:uF _wVI&Z C1j*rB!m
%v qN'DF5YB
char get_precede(char s,char c)
"I0ZO6Q(n3g ^g {X k-}c!C)t]
    switch(s)
c @1Ia*a6q l#J     {4NB4rqS^g?
        case '+':                 
c"a e]7F%[         case '-':
!rD d0@{6}U.k:Z              if(c=='+'||c=='-')
(@_'E"M#AiB$QX                  return '>';0r7w2iW5T'Jp:\$pv
             else if(c=='*'||c=='/')
`e"F_\j8X                  return '<';
T+gr"D{8s2hh+V              else if(c=='(')
$t y\ t5\:Y                  return '<';
8hYg)~,}!zS q              else if(c==')')J7u%zt;rMx)T
                 return '>';
:\h)v:bO s{a o              else
5Rb6h1c5v Rc                  return '>';
Dn-F7bME$}8Z         case '*':
h4tA$Emg[ Z&j.P         case '/':
i!Xu ]rK{)B ^              if(c=='+'||c=='-')NtY)\{&G&y
                 return '>';
j"d2vu(j,U"i              else if(c=='*'||c=='/')
{6sV!M9C"]                  return '>';+|Zo {wvW
             else if(c=='(')i%E.SkJ:miK
                 return '<';
2[!q5i^e|(UG{9e,H'G              else if(c==')')
Q1xi@`^)It                  return '>';
A V~6Nv4Z~              else
RBn'YLw,l                  return '>';
j gAw$l4vP c         case '(':dw"aAX S
             if(c=='+'||c=='-')
Pa.\{+eZ                  return '<';
|6@o&G$x'| B              else if(c=='*'||c=='/')1c/tv X9pZM
                 return '<';
rD5Rm zs9J(Z              else if(c=='(')
4j.F KJ9q,k(b                  return '<';
BpV9clW}m$S              else if(c==')')h} ZhU au5o'QR
                 return '=';
'ao'?M nF9l              else
:R.B"S(m1~*m6R~                  return 'E';?o+IklH
        case ')':
ZV,U%k5x:ME|z              if(c=='+'||c=='-')&PV3Uxr9q(w AV/Nt
                 return '>';
V5_#g%?M              else if(c=='*'||c=='/')
:hb/Yf3T+f+J                  return '>';UAX x{LD
             else if(c=='(') p Vn#C5w]cja
                 return 'E';aae3|7u7W3mg
             else if(c==')')
Aa&tL0r:Feu                  return '>';N+M rI[VmXt
             else1LI ZJW9Vg
                 return '>';U8m%N TGK#Z(H$BjV(}
        case '#':FOg6f4hM H(I
             if(c=='+'||c=='-')
1g(gLd3~                  return '<';~t J} z0a
             else if(c=='*'||c=='/')
wP-Wq Dq#M\U3u n                  return '<';+wf%~5i)}l"{"x[V I
             else if(c=='(')#O:w!P.^"BY2~
                 return '<';
?~ p;]Os6R2Q X N+lJ              else if(c==')')
C [@%X#rG ?m+Z d                  return 'E';;?B,Q4q(W#HED
             else zvz0{h {Sk
                 return '=';WasKusK7V c
        default:
Q9f;uN)a,jx              break;!A,f }!Ra&Q-[
    }
ss^b F:yL.zD     return 0;   
&Df^|,H }WV+cbi:l3N$N,np G
;w-R)R2A sy2l3@
int isOpr(char c)1z3UCI ];l({g
{Y6V6X%uP A DJY
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
/G.P5@4Qm         return 0; \-e)p]g"TH_k
    else
i5S8yc;T/Kuj*M         return 1;Mx}+}uK6n.C%V
}
p&`:M'l0Vb1L_
qr-_6T*u(|*FL7mk8G float operate(float x, char opr, float y)3H @-~Bw4f
{
2w)a u4L.r(h'h;R     float result;|#}.Q_|9`Qv`Yq2V
    switch (opr)
:~-F1X6if/V     {:oYfM4xA ^0D P7r
        case '+':
7`d~8l.p+zyT+W              result = x + y;
VW'd9tU1_(h              break;
1dilI{         case '-': y{m*\|
             result = x - y;
1T#H5M5h4^"C,p*mk              break;
@E5b].nc0T2W         case '*':
9WMU6^2y1uZ              result = x * y;1waN VH(rR
             break;!]JJ/GT\uWQ
        case '/':
a;p?G,h(^5L+k              if (y == 0)6K c&W B E IC"H/f
             {
2dyzw-z^Q                 printf("Divided by zero!\n");)Dw:b WBFu
                return 0;Mo|D[qWR*x
             }
2Q|F!n.F1hn              else
F,szY7vgzmb X              {
p jw ny(p6~6A\                  result = x / y;%]6\7]4N A Hd
                 break;mT:W*H Y4p3@/|_
             }
] f{,a/{,[9C        default: .W,X-N1Zz8P ^
             printf("Bad Input.\n");
u6n N6O1p6k              return 0;*|2i1N#v9}6d/T`x
    }(h$M a"pA4z'^
    return result;
i#s u3Z`ga1_L }    8{bBn?"W[x

3[!VHaU-bX float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
l5g I1{]&hA%[@ {
"^"S f.g;z%X @     Stack optr,opnd;E)@+mFZ
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
+_q#H t t%B#S     char c;~(yZ&W1h
    char buf[16];
(l#cf-h!yl,TQ     int i=0;
Np"E]D1X'{(fFR     'u ~S@6YT L
    InitStack(optr); /*用于寄存运算符*/
WxF*H7cjg_0sy}     InitStack(opnd); /*用于寄存操作数和计算结果*/!sX f i nE#PdG
    memset(buf,0,sizeof(buf));1zx i K v.E1SUdB
    /jQ(k(I{1z
    printf("Enter your expression:"); k W2WW|B"`"F
        
a(Ul2f?4QS#wDBD     opr_in.ch='#';9\1@$r+mVBL
    Push(optr,opr_in); /*'#'入栈*/0^8^1Nn#@tj?
    GetTop(optr,opr_top);!hGt Tc
    c=getchar();
%| jN5}o*W se     while(c!='='||opr_top.ch!='#')
Yu"fb| K9Q     {
D Mc*Q2`         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/)C!^F C? P@g
        {5m8H/n1l9t(U
            buf[i]=c;/@g\pt W6^
            i++;
!yy^r^MLPo!\             c=getchar();r,die%H"z ~zSz5^0l
        }
oC!sTNa         else /*是运算符*/ rh!t5K$k-QY
        {6pumGD4X JS
            buf[i]='\0';KE1L!T(y
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
P$v*U j*Nh             { YA5S-I%\7j_ W
                 opn_in.data=(float)atof(buf);e u?lU \I2N3Us
                 Push(opnd,opn_in); {y2pfE2a
                 printf("opnd入栈:[%f]\n",opn_in.data);
|Sq Le                  i=0;
/AN-zlQ4k                  memset(buf,0,sizeof(buf));+a h T!fua
            }d(w%H9aMQ R
            opr_in.ch=c;
a^Zp5w$z             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
|2C.|C S/w             {
^w%NP bC/]*M                 case '<': /*优先级小于栈顶结点,则运算符入栈*/;t`-mSRL Ma
                     Push(optr,opr_in);7u{%}!_ LuF%M f
                     printf("optr入栈:[%c]\n",opr_in.ch); f|G'Kg.S Q
                     c=getchar();
/h2Bw2k~Gfq2n Tt                      break;
U%uS u*w                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/R:_F&F5Z$bfZ/Y
                     Pop(optr,e);WU"_U U#\1X
                     printf("optr出栈:去掉括号\n");y&` mwT
                     c=getchar();"A.i,U TO
                     break;8rO*H"U#zM)w1w8l"]
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
.K0VdkQ                      Pop(optr,opr_t);
4rhvK6[7s                      printf("optr出栈:[%c]\n",opr_t.ch);
~.^~rS                      if(Pop(opnd,b)<0).Z-Ga'H;W K+c!m?
                     {O'ei.bHQj?
                         printf("Bad Input!\n");
bb3@CK W bD/~ H EP                          fflush(stdin);m1sw D.ZD V
                         return -1;
;fkuH7b0X;f(`A                      }*K!\-?"v)ic,Y#h
                     printf("opnd出栈:[%f]\n",b.data);D!g's4r|r v
                     if(Pop(opnd,a)<0)
]5NPu }bD%VS)b                      {
8x1xg/tdZ5x"_                          printf("Bad Input!\n");L Q @5d0|
                         fflush(stdin);1M6H r1V%@jkL7f
                         return -1;Y {e;~ c)Ysy
                     }
I#r _Kuy                      printf("opnd出栈:[%f]\n",a.data);7hYHw@)e
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/vH6V$mR)cYa
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/C J?^MIy0Y%d;[ m
                     printf("结果入栈:[%f]\n",opn_tmp.data);
[eL$q2d{                      break;,j k2I}0|s'Ny0|
            }
:ki;})O%BU/o4\         }8p%E7g2s X4Z1g
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                wOB`D\wp
    }
W"iQ*y'E,Kd;u     GetTop(opnd,opn_tmp);
;Q1DkBt!bS7q4K     DestroyStack(optr);
L-K{[ I u     DestroyStack(opnd);
y{v-G5Lo     return opn_tmp.data;P wH+}eS0~e5tG{_2B
}
aKi%z a*E ]:Tbv1K j*j Y7s1i!b*D\&G
char *killzero(char *res,float result)
*_)w7jX4{5p {3H hU,s,J:\'d
    int i;
M1u0E;h(Jq2n'x
2d tVn ^n'Wu0~     sprintf(res,"%f",result);WP?-V/L/n0Vnrd
    i=(int)strlen(res)-1;GPx@f7V6ife/Q
    while(i&&res[i]=='0')
p%UBP:n     {ZrY;z(Z
        res[i]='\0';
Ajh Q-L.mH         i--;
0m7m'}/u#CW,C     }yl6WOm2z w
    if(res[i]=='.')hO2A#KUfWVk-a
        res[i]='\0';*],\;O9_e/{O@:aG
    return res;
(g.VfB;e#s5e{R)o2W }
L+R^!Z2j%z
J.D2W;I CQ int main()
[z!C k Amv {,uEXU_ K
    char ch;
v)tl(S8A(Gt0i `:]     char res[64];3Hs+uJ;|gC'K(Z$Z_
    float result;_:m h-q'M
    while(1)
-B3N`XwF     {
^Pk9rH \G9h!n         result=compute();a0? @K:BI
        printf("\nThe result is:%s\n",killzero(res,result));
5P2k{4t3YF         printf("Do you want to continue(y/n)?:") ;
)I,Ceif'h+fB0i         ch=getch();
vkmS+sk:o;jQ         putchar(ch);
Gdc&s2F.Q{ju         if(ch=='n'||ch=='N')+E/UMHF6~y|x
            break;/|BR/\8M
        elser^4y\rS.T
            system("cls");L"Z5KhGbqx8u
    }TmJ(sm/|8GT7\
    return 0;:H8^i1q&G,~d{!t
}[/i][/i][/i][/i][/i][/i].\1av@~,y#X6|

f0KS9]"Jv+? [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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