捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.[C0W6L(Z.I Zh!|
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= m_n;rg
/**************表达式计算器************/
UPA1OSv #include <stdio.h>
C|7[ F,s #include <stdlib.h>x8Y/ld;w0?G/|h4H
#include <string.h>:n-J?8L#tf$brQ
#include <conio.h>"hJ"c:A!W5| kT
#include <malloc.h>.EDVP v A%iw
;P5uns-f/h-d7~
#define STACK_SIZE 100
4T%c'B/Fc #define APPEND_SIZE 10g3y7{4]l2Z)gX

Zf#?;ajj struct SNode{
r@8G g-wr4wu     float data; /*存放操作数或者计算结果*/}G:Wx y(~
    char ch; /*存放运算符*/
SMmh~AX };
A&o k!iF7e5_K#ydv
u E&X9GOl struct Stack{
/o3K+] m~+hN2Re     SNode *top;
B8X F2h+Gh(a     SNode *base;`/nRt$f6_4qU
    int size;]_0K3F,Ku
};
9}p} I)d| ey;h8v5VCk
/*栈操作函数*/
*HD5JQ~#|#c'`R|G int InitStack(Stack &S); /*创建栈*/
*XX-o(p*t)hr int DestroyStack(Stack &S); /*销毁栈*/
5VQ[ L+I$v~;y+k|]-t int ClearStack(Stack &S); /*清空栈*/
+N"O(q2w,_9W{ E int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
ZT9M},}:U+FI#} int Push(Stack &S,SNode e); /*将结点e压入栈*/L;[$}0`,p0k
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
+W2fvD8Z'G/u+m
_nL??1O6KHV /*表达式计算器相关函数*/
5_"Ou^\6t!H char get_precede(char s,char c); /*判断运算符s和c的优先级*/
/S5bq3p-b5C@2g int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
,O q8[3p{c float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/4e"?,Ja)tS6FE8i
float compute(); /*表达式结算器主函数*/#@6~6i.c }Sq y cMD
char *killzero(float result); /*去掉结果后面的0*/ BrqY0Sa"e
C2].JMN
int InitStack(Stack &S)sl*u/ON#eid Q
{JR5M4C q Jv l
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
Z%B H6X[P     if(S.base==NULL)
z9H#H"g5bs     {{|hE/vt wM!I]
        printf("动态分配内存失败!");
1?8m[I[.uH         return -1;(M:h6G"L]
    }
%L.qh4E-ET*tp&]t5[     S.top=S.base; r/y s6T+qX-`
    S.size=STACK_SIZE; ?w/Db8jZW
    return 0;.f}$n#m7uNN-b
}
2WYTqU"@
^(i2AqK"?,H int DestroyStack(Stack &S)
\/f|"eG*X aY {/b.i u&aZ4aT
    free(S.base);
U w;zm_'X+@     return 0;
I4A5B(D;S{a4R }
%jT idn#i J0WPjxR.gD d
int ClearStack(Stack &S)X6l NU#V M)`,~L
{n[Z0s3A0j
    S.top=S.base;
SPh%fBh     return 0;
g5t+w6r7KO] I }
o3cX }&nIB
[ `6tj:vP int GetTop(Stack S,SNode &e)
8|(s$i4lKdQ {U fT^M.[8Rv
    if(S.top==S.base)
V2@9q)W5m)c6pmV     {5q$B sc!TL V X}
        printf("栈以为空!");z']'aO[9hV
        return -1; w'L,`2r"lk!G h
    }B7m1z@f[*u a#A
    e=*(S.top-1);
S}:sF.I     return 0;
mmc M1gD7_ xSf.|d }
J8@0?\~7b.p!l6MC/uN d n4|[ yq kW|1hh
int Push(Stack &S,SNode e)
M}-W(`!f2m+Q4C^ {
G4P%d4Z V;?G     if(S.top-S.base>=S.size)$M-k| I!oU
    {2s~.})o`-\{
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
nu4d(f*M6G{4V!@[         if(S.base==NULL)+f3T}th T2I
        {
} [WYtJ3~s             printf("动态分配内存失败!");
Y9q1~p5?,\+hX             return -1;
&S(n!d^ ~6i#Nl         }
A }SE2E7n         S.top=S.base+S.size;
-?rW's&~)E/l1s         S.size+=APPEND_SIZE;
!jQad8Ua7\:Z j-b     }I`)i^v@,S@
    *S.top=e;+s^.Zufi `
    S.top++;3}|(X8i1v-a
    return 0;
"Rx.Le h }]/gxe5W CH4E

:{Zg5VG{ int Pop(Stack &S,SNode &e)Iv3XZ5j#U:l
{
QgV8q~*[M.\     if(S.top==S.base)/Y,C|*ap
    {
@o.v7JW!HL         printf("栈为空!");
"M0_Gp%[]         return -1;
2woO7b:m*R4Qk     }
^)K/t-H&`SL |};Nk     e=*(S.top-1);
8`3m*_2?S9lm     S.top--;Z \qtC'X
    return 0;
y6dR9G*R4|"l6i]'FE3j }2jt D/I(@b
D3Wk#PNk
char get_precede(char s,char c)9R n2t(o/l8`M
{
W3]2@(N9z(^a:E     switch(s) g'Qr!Ff
    {B0mcF6k bS:|I4^
        case '+':                 s,x0fR0K7g{ L
        case '-': k*b5P3Hia6H%u
             if(c=='+'||c=='-')
$YA0h+O&j4n Mq                  return '>';x#z$q5Ks6uvOR
             else if(c=='*'||c=='/')
N~ffAX{ m                  return '<';#e}vK ]0w4E)t,Zy/K
             else if(c=='(')f:U-c4H6QE2i)V
                 return '<';v'Z Y(N(Ts
             else if(c==')')
/V5t @@3t%N f                  return '>';
F-[/T3`T.G)d              else
5` O4b1y Mm                  return '>';
o!Gl8j7}fH         case '*': A+r w$w0k&l
        case '/':hGS@-pF.?O{x
             if(c=='+'||c=='-')"rd^.h c
                 return '>';5B!O6](^6h E];^ E ~
             else if(c=='*'||c=='/')p t-AF z
                 return '>';
4N._Zzi#o,^"D{o              else if(c=='(')
*C(Rj a \!aDBG                  return '<'; u;yEtk(Y
             else if(c==')')#pO!o1_:Bi
                 return '>';
P'cQu^5@$J!a.k              else&^ {&Y e'[c!SQ
                 return '>';Bf0bP$HqOM2d
        case '(':
-A#t+exo5Ss6G              if(c=='+'||c=='-')
`m m5DaMbn j                  return '<';
)e K$|1Jkk              else if(c=='*'||c=='/')Kp'{"TMz
                 return '<';Q6hP0t0[m3s1t
             else if(c=='(')$V'w8t,j/LK9xF
                 return '<';*k5b:z;F+GT*f1W%I
             else if(c==')')
EQDmVE                  return '=';
|UI4B/{e)J:y              else v+u0e)wa
                 return 'E';
"tn/p,U9A ]5pt"JqJ         case ')':
rg)dSo l!g'L              if(c=='+'||c=='-')
0e5E H8UNK U                  return '>';S*g3Wyi,J!Ed
             else if(c=='*'||c=='/')j}hqX `U^
                 return '>';
-q W4[3L4C              else if(c=='(') m8a;bPY'] y
                 return 'E';
#n0g-`&VA kN6c)q6q              else if(c==')')
@n+H*M!t(J                  return '>';f6^ R6i$SI1Pfhp
             else
Q8R!aU:p ?d                  return '>';(R!R2D!w\'O(`9eN
        case '#':){.e\bJ9N }j
             if(c=='+'||c=='-')2O2t%O/c1t x0L_{h
                 return '<';
y i3[\I,e4a*?              else if(c=='*'||c=='/')VYn.E%{4T7V[
                 return '<';
4d2a `(GD\3SFb\0|              else if(c=='(')BSk,nE5w5r
                 return '<';
*nR+P^i J3l9jJ({              else if(c==')')'r3ZZ)x:{)D
                 return 'E';&IL~0indS7a3O*p+p;x
             elseu&Ix1I ? H
                 return '=';
K4^5nT1YE;a         default:+fv9f'U~VO3q
             break;.Cq#fo)jdJ
    }K7VKpLU;`
    return 0;    f)D Y%|Y`)tPd
} Q Nr e-y s.FHb

x2Q!I7Xz!Y int isOpr(char c)
!h `0[[UmLnP {&x2D @IL6MGM
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')^W~5}k b
        return 0;6?M;GX,H,^ W8s
    else ._ ] Fju5H
        return 1;
*g!\!@_0@eE,x7YV }i%da\i

4t Tp$aIa&K float operate(float x, char opr, float y)
,FO:r{G2KD {
OP![6jq V6N-P`mC     float result;'dl'{|:U/Xs
    switch (opr)
u4b&U4b X S9['o     {
/wf-[J+I)a E7F@         case '+':
b3rO{JD\9ov              result = x + y;
g [F;Yj*x _-]              break;
v B2aSPa         case '-': y&B"eO7|Eun
             result = x - y;`7s-D*G3i3Yo
             break;
5|+`,]I| C         case '*':
#N Hvi4E$w"w              result = x * y;;]X5sX~t
             break;] Rq7E-x${
        case '/': /y GxE)S!i
             if (y == 0)
fILS-U*W ?              {4I{:a9Ju e'Ol
                printf("Divided by zero!\n");
4[5[-TB9HT                 return 0; J#} ]5m,H f:G1g2T!S+^
             }
A-?PghtX TK              else U.dQ@.Zt4a
             {
H6]8fxGrc(rd                  result = x / y;
1_pUMF9SD/N0B                  break;
7xx:u T5z%b              }T0mz\ N/Q8n
       default:
Xs~ \F4EiD              printf("Bad Input.\n");
}!HsI3ArY              return 0;
*I&L~5I7~ qR*r](K     } xGo5~Q,js+\
    return result; \\;kbarUJF q
}   
2k? `:B*\Zs
!|._h3?3`5@0Od`/E+rS v float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/-C0@ _ vN$Q
{.S L l_ud.E
    Stack optr,opnd;})Er)n']v.db
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
bC&|d#D%v6{5k2r Rl     char c;
"g(G*E]\b#s     char buf[16];
9S\T`X     int i=0;8u zn0WiS.LE0^fzH
    *FHNpBoE^+\7L
    InitStack(optr); /*用于寄存运算符*/
|a l7\6o!fp     InitStack(opnd); /*用于寄存操作数和计算结果*/
!X V2@7F~Jh `G     memset(buf,0,sizeof(buf));
]+gg'vb Cd1y     JJdBEM$|7N
    printf("Enter your expression:");
jm:~$DX,BXd(m+} n         Z"v)l+iN
    opr_in.ch='#';
O"I2E'|X5a5s.v#m     Push(optr,opr_in); /*'#'入栈*/MK-Z#U kRy@
    GetTop(optr,opr_top);`v{(|W q~6x2V
    c=getchar();5fb5bP.h P U8M1s
    while(c!='='||opr_top.ch!='#')
:Ef7R"IT     {"L+`l;k%bS
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/!g9pRF1_ H
        {
$r5hZ3O t`             buf[i]=c; ?%J i"Dv h
            i++;
y@!b7^B             c=getchar();
T OnI&{$f9Er)a a         }:B K8]N]sG T
        else /*是运算符*/
gfJ4}-rT&n0r Y^         {V+hg_f&o [+yo ` _vK
            buf[i]='\0';
0x:F)DQR[N             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/} |l%e*Xr%c
            {1A@ e%brA!XH2^
                 opn_in.data=(float)atof(buf);.{6J"sl(b&v.J
                 Push(opnd,opn_in);
#cfD^R+z0{pP                  printf("opnd入栈:[%f]\n",opn_in.data);
,Vih MS^;t CJ                  i=0;
.H'a)`v h i aE                  memset(buf,0,sizeof(buf));
)|!Y.?Yf0mK             }
}v|}_S0]$n             opr_in.ch=c;,q"g-Rl:SK]5c"zAD&ER
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/i0w ~vb
            {
C/X*} ?\\2y,B^o                 case '<': /*优先级小于栈顶结点,则运算符入栈*/i$XM X1? Q%i#nC
                     Push(optr,opr_in);
'J)gO.b,`([6v m                      printf("optr入栈:[%c]\n",opr_in.ch); dc&U Dh
                     c=getchar();
c byNl"e1K{                      break;
B7[ZU$u]-X                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/"X3IA!Xtg+A@ x X@_
                     Pop(optr,e);
}!@$xu$s%\ U"U                      printf("optr出栈:去掉括号\n"); K9ILv;P*hi]$O
                     c=getchar();
^^/`H*Tg                      break;
CnCZP _fs#LV                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/#I"vK;w&l0? _*?
                     Pop(optr,opr_t);1H XUM&G)\U
                     printf("optr出栈:[%c]\n",opr_t.ch);|.^ Q*[t)?
                     if(Pop(opnd,b)<0)
#QC*k5o7C"x                      {
`L C:^HG%Rq                          printf("Bad Input!\n");
-p?[2V6V1um#]}                          fflush(stdin);
bu1b W}fT\                          return -1;
J!Dj:}(z8vf4H f#r"y                      }B"v)r`h
                     printf("opnd出栈:[%f]\n",b.data);p,[E Jf+E IB$t&Q Zo,J
                     if(Pop(opnd,a)<0)$C1}q _ xO
                     {&c-d3o)ld-ih
                         printf("Bad Input!\n");
sW*`]~&Pnm:v                          fflush(stdin);
5eC4H&`8J"Ml@                          return -1;
_z(L-F)?:jx                      }
#m2Tw/v^ZD D                      printf("opnd出栈:[%f]\n",a.data);
5~'^w1Jr]d1r%\                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
4eby$W(t^3q,g?x                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/t0OJ$I:f$~cs g
                     printf("结果入栈:[%f]\n",opn_tmp.data);Z8Osdm'V%A
                     break;
/s8JR*Jy q             }
?B]3V!H)q         }5V F?&R%@Cy~
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
x$m"O}gc:`pyd     }/\,]R}M^OJ-\6Z+n#x
    GetTop(opnd,opn_tmp); d1P&P WS2vd.x
    DestroyStack(optr);Tw-N;W aL6S
    DestroyStack(opnd);
w&Ym;Vm     return opn_tmp.data;5lzwU!Q]
}
H'{@8GP)r8N` F+A O F0j|WHs4G1v
char *killzero(char *res,float result)
8fo6g8U pdO4L EF {dB5C+?8j {
    int i;h v%{0As+kK-N1R

2?tyY(t     sprintf(res,"%f",result);
h2K.\ cK&vOn     i=(int)strlen(res)-1;
,X[ JsF(v     while(i&&res[i]=='0')B.p$q`Ef6Q
    {
i#lQ]Wv         res[i]='\0';v't[?^ P
        i--;
gGZ,t"Gn3x~     }
%P*xw Y9cL     if(res[i]=='.')%fcw#R&d4s.@Rh
        res[i]='\0';2Zp~ `JuV.G3ql\([ c
    return res;9] l(O1x(I u
}
2O*WfP&@9f1@ CT:\g ~(B:t*e
int main()
7w-y3`S&w {s1I7EeU:\8n
    char ch;*C]KU#A
    char res[64];
,gFB e.Ea ~0H6R9E     float result;
2s4MCY{$b     while(1)'z$F8P-fOr
    {l |Cq.f1_J_ n
        result=compute();3cJLK0j/z%i#J#L
        printf("\nThe result is:%s\n",killzero(res,result));
Vi7X!P;Et         printf("Do you want to continue(y/n)?:") ;
BU+_D]A+RkDOF7c5x         ch=getch();
$a;GC'YPBnB8r         putchar(ch);
\WN,D}jP5y&X Q         if(ch=='n'||ch=='N')su.c(N!n'KX1\
            break;
$k(tL$^!A         elseS`5w@&zu;h+m?W
            system("cls");
4oC0n`&od1H}     }
{,I5ALv     return 0;
(z%~7{i!L m }[/i][/i][/i][/i][/i][/i]6U9n&~#m!^
_0s(fK*J
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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