捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
T RT6e;_X p 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
#NBd:X,B /**************表达式计算器************/
?&dbQiF(}u(d #include <stdio.h>
^k&u+z,H$v #include <stdlib.h>
?L!r-aM?;C7tv9F%i #include <string.h> P2^[0m*[H
#include <conio.h>nS }*eR9}
#include <malloc.h>@4t1M-dnN

;o#nAt5F,W%D #define STACK_SIZE 100)Am y w^y5hh
#define APPEND_SIZE 106Wl:Oh|mY)RX8e$Y

mM"U)V&Q M'q struct SNode{{.Vg7aW3Vc Sd3h
    float data; /*存放操作数或者计算结果*/'`v&_J5lhWa8E
    char ch; /*存放运算符*/C`#o`G V,i7P h
};
fx&Vbrhn lM;R }sp~ v7[
struct Stack{
0NX9?^T$_I;h     SNode *top;_$nAT|g?
    SNode *base;
Cy2p-`"N}     int size;FB:l'uuzE
};
5Fdg M{T6D
)Ba6V `P /*栈操作函数*/
V;?y9Nq%W$o+UH int InitStack(Stack &S); /*创建栈*/
5FF lM_9g~3Y int DestroyStack(Stack &S); /*销毁栈*/
:Ue:aM)}OF} S"j2~ int ClearStack(Stack &S); /*清空栈*/
UH/l8~"J%j-R5i4Z"j int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
!`ON*x'\*p int Push(Stack &S,SNode e); /*将结点e压入栈*/|"R%Qc;sc6J$?vk%M
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
%_M9V4x/D_:}$?|$D
0Tty^!vH a /*表达式计算器相关函数*/
5p#fRIo9M@ char get_precede(char s,char c); /*判断运算符s和c的优先级*/;q(W ``i'}CE3b
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/P(|8[\u
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/?z H_-T
float compute(); /*表达式结算器主函数*/nk HH z%C^4[;W
char *killzero(float result); /*去掉结果后面的0*/ ,KO-_m,`

0K0SQ*n F7oW int InitStack(Stack &S) H)z4D,t[
{
DaM:EH'X     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
|3u*v!E$dB     if(S.base==NULL)
"_6W2v M5]C,C N     {
6UI/t2j$j Y,E0q Cm*y         printf("动态分配内存失败!");"B3L(B&V(N#_
        return -1;
ISV4JtZU     }ooD+[ F\.C a"UL
    S.top=S.base;
A4CVDk"L8KY     S.size=STACK_SIZE;by QEY(vasv
    return 0;
5O2R*g5Bs }
nVsAp9s(|nqM 2E:Vjf.c
int DestroyStack(Stack &S)7EHfR-H9j3TNM!MA
{Eo"v D#Z;Qa
    free(S.base);
T/mOv(U2Ln     return 0;
%}6h.n"lmR }
W R3kf4c1l Jy+]bD!@
int ClearStack(Stack &S)r7WQ*]!`;y;KV
{
pBZ\4Z Z     S.top=S.base;
ta_2P^1?     return 0;
#K ]n j {"j y Y }1l S6](i1f
'kN^x'f y:T
int GetTop(Stack S,SNode &e)8`-M b/@k
{
*a h1r1XN*e%b_5Y     if(S.top==S.base)
0Pn?c/c[,t.l     {? `E"i"Z#Q_
        printf("栈以为空!");#G$bD)Dd4Rr
        return -1;
5MTiHx(G     }[/@q3[)F6Bp$dy$r8V
    e=*(S.top-1);
^ {,{g/q2v M L     return 0;
U C},Y0h)t }WL[O7@+l_7Q} `
XHi*SO;o:]%X/T
int Push(Stack &S,SNode e)+_ ~oDXDW3E{+a(N
{
:S0]0~-IW)}2Y4T1IT$n     if(S.top-S.base>=S.size)
a#Rd;m\y+s3G"TR     {I+zwimtY/|
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
DN~e&M v Q X(oI         if(S.base==NULL)
hB"q3x.lA         {
)z'_2cH|)i             printf("动态分配内存失败!"); k0ns$F-g/h @-}9V]
            return -1;
_hP)m,R @6aHi         }
(Z @ N ntE         S.top=S.base+S.size;/d:D;Xo~[ca
        S.size+=APPEND_SIZE;II [iD*~
    }
?&mdm-[h:Q     *S.top=e;Mf.jW/VQ llF
    S.top++;
~7ZIo~;Eu+J.ni     return 0;IK"S5S_6O5}
}
s3o6s"kX0h
~;G*g A#q'JyMs int Pop(Stack &S,SNode &e)4r1pSR+G"c{6|G
{jS:[f4A-t
    if(S.top==S.base)GoD)d}(o;AJ
    {
l0m#yz Wd V[I         printf("栈为空!");aU5JW@j6v:O4E w
        return -1;#o,h,l:h)\8E~s
    }+D%z6a]bx
    e=*(S.top-1);@4_0Eq n9v9v
    S.top--;
-tmYf#@1vM1j;lx     return 0;!EH,W?"p#P/Z
}4F&B wxi.\[-Y

P3P.M0o!H/FD J} O char get_precede(char s,char c)]\+IOMyeF
{
I\.|qK!b ~/x/O ^y'FC     switch(s)-CCy+k m F
    {
;LR6Ml8ByTU*v         case '+':                 
zE.U t+{rb2L;\|         case '-':
/o{[+YHk              if(c=='+'||c=='-')Us+Z2ke^%P,R8[:q
                 return '>';Z kr%q(xV*Mn
             else if(c=='*'||c=='/')
a!HO`V P                  return '<';
by2B;y[/l$@ F,Nq              else if(c=='(')9UhGS2Bj
                 return '<';
3bG Xq:B'y2^$Pd              else if(c==')') Do pjy;m
                 return '>';
$\dt;AHYA              else
2| }.X-x&`1b+Z}                  return '>';
h*y-VHvs+q_Tl         case '*':
*i:QKZmX4o         case '/':
!HI };n.SK              if(c=='+'||c=='-')
4Hc X T!Lc                  return '>';
:w4bn!] m/W0`]^ zc              else if(c=='*'||c=='/')
0mh8kZ ^wZ                  return '>';
2I ]I P;g&e              else if(c=='(')f2j)K9Hl nO&r+o|
                 return '<';#\;T&[3~'d&bN9u%e
             else if(c==')')Zh.seU3fqA
                 return '>';Cw3PNk3V,Z g
             else
0Y^"?6c"B3d C                  return '>';
vB:]Qf;U$O3s+SV         case '(':
t.xuR0u1[&~              if(c=='+'||c=='-')/|#x4H*c"b3G
                 return '<'; TJ4Hj}Tp
             else if(c=='*'||c=='/')-UO'SJEQO
                 return '<';|SS^4I/V m{
             else if(c=='(')B ];`.Hvq8]
                 return '<';#c2{*Y'Y9\2DL
             else if(c==')') Fp E#C!YOK
                 return '=';$ekr G,N?
             elseW gApCT'@
                 return 'E';
QmsoE#gL [         case ')':
uWK5`9_+|;T              if(c=='+'||c=='-')
,gqz7{,C&PQC.j{                  return '>';2W:k6KXvu+ZI
             else if(c=='*'||c=='/')
!^*B&\1kx7JPG5F                  return '>';
} ut g4Hr/\              else if(c=='(')
'M^c5Axh6u                  return 'E';
'e {4j3V8l              else if(c==')')&z9TIhw_%]0mE
                 return '>';Sw.Cn-U8E,]2g
             else
7?z,["Z}A8ie                  return '>';+a1T0gu CYs
        case '#':
L.KQK$W6C              if(c=='+'||c=='-')
nm,wq;~IHjT                  return '<';
MaA,e9M5n*z              else if(c=='*'||c=='/')4Kw;_GknK
                 return '<';
.Dp^3HLdu              else if(c=='(')
g[3hB`Di                  return '<';8mRZ B!|-raUW
             else if(c==')') JM0vh%R3b9p
                 return 'E';
!g6No Z Q5l*@8a?              elsey'Z a9[a8{
                 return '=';
6^)])^ D4A3h         default:` QRl#?h.j2S+F9^;w
             break;
'D r ]Y)o#N};t     }W#aE0p6T
    return 0;    7Y:Y3F\S
}f P4Y e&xq H\:A
nsV5T&r W
int isOpr(char c)Y4WAYrE
{
Z$H ~4kkPc ]c     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')2D]t]t0mG!v`5oS*h
        return 0;
Zb-H:{twk     else 6r0bdSs,o T
        return 1;W$k"xD~ A
}h)Q6T9]bc:p0qP

Bxu\(\$oa^-XU float operate(float x, char opr, float y) Ea(}!S;DJ{9U
{OX S e]X2p~}
    float result;G2T Ai4Z$o+iz
    switch (opr)
*Ti0T2iN1Qm[$M     {
b9g BDNvaz         case '+': C+BrB:g Gm)B
             result = x + y;,R\G#b-wc!z8Y
             break;J.mC2t+~ C!`k
        case '-': t3Mm AZwEH
             result = x - y;
~ N6m zlH`9l              break;
t0RxqSo_:d:U)x1L         case '*': -Hh eq&I Z
             result = x * y;#z4c/X.p p-u3gf'~
             break;
/d"_%fRK#|2oT-N D(O         case '/': %TQi~3@7r
             if (y == 0)2~&n${+H8FJw
             {Sk,AGZ(i;L&iyW|
                printf("Divided by zero!\n");BU2?l OF7|9Y
                return 0;N'Z B w~2gkB:y9v`5a
             }
2T,qL2P`(Y0lI O2PAG.J              else xf E9J#l z
             {
#\bEm#A b2j,B-LT,{                  result = x / y;
&X*w;R)YLs                  break;5z'\9_ z!J9W
             }
g.V W'@s@        default:
N"^,im?;e;y              printf("Bad Input.\n");
a+T B/k!G              return 0;/^|[v^z*v;D}4t!^-m|
    } uvlPpXF^
    return result;#o]w6Q-cl
}    Z w gOQ+K*e_i

(|M0_s8D'R)~ f9C float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
"m3g0dR"kH5QA,p {y8odc{?} Yq k
    Stack optr,opnd;
v2pFC"ItOV     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;o}eI(z
    char c;TeU,}p;m F@p/v
    char buf[16]; D{0f)L,e0YZY
    int i=0;O;Z3a ybBz7G
   
,K6OF}@7CA:_idr     InitStack(optr); /*用于寄存运算符*/s,aJ9l,Y,m
    InitStack(opnd); /*用于寄存操作数和计算结果*/1M3oBJ$}W
    memset(buf,0,sizeof(buf)); dp5tz,gc
   
wnj]yZ ~0i+g     printf("Enter your expression:"); b.E2j,k!tLv\
        pXt*w#bS:BAU
    opr_in.ch='#';nPM4|'T!QL
    Push(optr,opr_in); /*'#'入栈*/+yULrtwb~7J3R
    GetTop(optr,opr_top);
?DIV9Za[1O     c=getchar();
:P"kZx oi     while(c!='='||opr_top.ch!='#')qgc hgw9Q
    {
`"?NZ,\k {s         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
#L$Fq:`%u:G6\{v         {
SXRNf0JK8aH             buf[i]=c;
1S} z/T"r!YU B/E             i++;/B1BR[@X)S
            c=getchar();Qmo2IM#I|
        }
/v)A7B!]3u+[:`M         else /*是运算符*/
ECkW{4c8O         {
8Gz U d)?|             buf[i]='\0';
Y w&sq a*m]             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
x*Mi0i*r KR:_M             {k,i.v1lb&b
                 opn_in.data=(float)atof(buf);7x6x.e;Z8X+eM
                 Push(opnd,opn_in);n8XiCw
                 printf("opnd入栈:[%f]\n",opn_in.data);j:Y1x*~} ~;M!pA
                 i=0;
;Tu+c$Xp \{                  memset(buf,0,sizeof(buf));
Wn4H*Sd!KkO             }*Gf~$M1Z0[1q
            opr_in.ch=c;
R&Sh*}#^U             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/hL$I/H-?d
            { SN.Pb m Q?~
                case '<': /*优先级小于栈顶结点,则运算符入栈*/J5m5X(M@+G'z Q8i
                     Push(optr,opr_in);
~7iP:w3Z:p\ b6~                      printf("optr入栈:[%c]\n",opr_in.ch);I7gIOt
                     c=getchar(); lxol}n
                     break;@/G&j'{T7qK
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
ph?&m0S/yH uE                      Pop(optr,e);.W1m;zsC-N#sm _"n G
                     printf("optr出栈:去掉括号\n");
^OT5{ XXqS)r(t%L                      c=getchar();2Z&tNxRP
                     break;,tJA%T'l]
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/M]+Q)BHb"c"MV2C
                     Pop(optr,opr_t);._6`,OV(HD
                     printf("optr出栈:[%c]\n",opr_t.ch);3IkhT:c5x
                     if(Pop(opnd,b)<0)
k7f5R@4N)h                      {
#|XJ[p$W!g                          printf("Bad Input!\n");
5d2Qt0}B$f;L_]                          fflush(stdin);C'o:f |#N@2fhO
                         return -1;aUv!s"bY"_a8\Y/~
                     } J`*s+Fr
                     printf("opnd出栈:[%f]\n",b.data);
w JP*R8tk                      if(Pop(opnd,a)<0),~2b]+S'h
                     {evMtQ7{4C
                         printf("Bad Input!\n");*O0U] sHz
                         fflush(stdin); f&AmPM1vk"G-K"|_
                         return -1;
!] ^AG1{n/m*l                      }+sC&sj6\ t
                     printf("opnd出栈:[%f]\n",a.data);
e9x N+Xh4h@,_@i                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/"u2C)r-o7wh|)s g
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
U6q(R%W l                      printf("结果入栈:[%f]\n",opn_tmp.data);9^;Y$@r+dLbB
                     break;
\g)w:`'w nU&L             }
)bJC @U$B         }&gGlMKB*?X ]6s
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
;H8S3h.J4k2HF~7L     }WO(o'oQ2u
    GetTop(opnd,opn_tmp);
"eF)HPJ3[ eV+e I)\4U     DestroyStack(optr);nA,giwgf
    DestroyStack(opnd);yi~0i Y8t)v faq
    return opn_tmp.data;L kCYC#KXF
}&B3s|Mi/?

xy5Gx6o#\?ix char *killzero(char *res,float result)
)JgAF%|d {
@7rU3@'p1Z     int i;Oc/]j*q
t2|Yzpd
    sprintf(res,"%f",result);
%x!y_%o0F4N8A     i=(int)strlen(res)-1;$K$Wv8o@i
    while(i&&res[i]=='0')s+{t D'jCEk
    {
'}%N b&m^8rR*_%vD^         res[i]='\0';
YF.s Xg%g V$a#m5u         i--;
Do w#F6`7X     }
a9i3f6O^W Z     if(res[i]=='.')
t{){~ W*i+f         res[i]='\0';
M Y&d,im6|Kq2B     return res;-TX.e.cF t*c
}
g6a\&L-k)Q dvJ
l$~O[7f int main()
8soN.vC'l H`8}.V { y4DZ2k b
    char ch; xXVb1c6d(xK%I
    char res[64];
J*NXxGU,F     float result;Y:ZeS/} n
    while(1)
#s/b Y+}0o2I     {J'y*r z-qG8m
        result=compute();)_0X*@Y.W7S @
        printf("\nThe result is:%s\n",killzero(res,result));
#}*\zMxNL^#h         printf("Do you want to continue(y/n)?:") ;
d-f;J*E$N5K6h*L6z         ch=getch();
BAwfu9st-`         putchar(ch);af8|7vTqn
        if(ch=='n'||ch=='N')6kv5o"ho&{qV0j
            break;
0V"~9r-R2jS4nr d_8}         else.`N*YS8Kv@,K:g
            system("cls");
!^W3K|;V)\M;B W     }
j4YH1Z].eq     return 0;G?4Kt-\&S.FX%Z
}[/i][/i][/i][/i][/i][/i]9c!zn4tA3S)]dL

Ct|\.mD [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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