捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. ?8f&M!MW0D a
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5PU7y/]h
/**************表达式计算器************/
uw-B7}&B-gt,xc #include <stdio.h>)daJ,|j"Q"u
#include <stdlib.h>
@\k-v ^ K~ #include <string.h>
Lf.ge0K6T #include <conio.h>
y9a D]o5nR Q5xR,bO #include <malloc.h>%@.m8]+H^
m;~Q8W0X3MR-B
#define STACK_SIZE 100_7d/`(s8o7a3{u:Lu
#define APPEND_SIZE 10
8~0|*J F b
CA e~+oR struct SNode{
|&a g {C+{     float data; /*存放操作数或者计算结果*/J)n3x tVF
    char ch; /*存放运算符*/
g}Z8\U'{\ };7m3eL wSp9~l#i
s1E6w`a4u*A
struct Stack{ v K;q"]&X
    SNode *top;;qm{Wc_{s'g
    SNode *base;
k(g4R[)?Z p     int size;'W:]h,OB
};(Z e8mU$J"Zo2p w
?y)BJ+y7X3Qg
/*栈操作函数*/'yw,RpSe
int InitStack(Stack &S); /*创建栈*/
`^ rc^e:C9} int DestroyStack(Stack &S); /*销毁栈*/*\!{{ dM8_(TJ
int ClearStack(Stack &S); /*清空栈*/~:['f e-E)XG2s"R
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
#Q8\bt&{5v~)oK6` int Push(Stack &S,SNode e); /*将结点e压入栈*/*X2u.C*zi5?!@y0Za3oe
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
b;~"vvo Sc3Or ,Vf:X8b0t2AR
/*表达式计算器相关函数*/
/VIZ7WY#L char get_precede(char s,char c); /*判断运算符s和c的优先级*/
J$vk+rn int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
hDTo b|J float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/"Q A c_c3e(t
float compute(); /*表达式结算器主函数*/"B.q5oL&N^2h!R
char *killzero(float result); /*去掉结果后面的0*/
!x)~G:P)bT
z2@&o0w6]Lzn$c int InitStack(Stack &S)4d4a$c5}"s
{Yn5cZP
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
!V3[/kg~3T     if(S.base==NULL) O1g}S NkT2U
    {i.k"O#JK(g;EJA2k
        printf("动态分配内存失败!");
L.GJ'[Gd         return -1;/Bh5u:EkB,_h^&m1vvD
    } B"Nk?/W-c/} U.C
    S.top=S.base;rHL@'q SQ
    S.size=STACK_SIZE;1X_c&Ni.a6u(b
    return 0;j'EX-Y-k+H
}
;RF(\)sl&\-dx?'B
1L!?~/m ~ E K int DestroyStack(Stack &S)o7u6b@;K3oX5u
{L'I:K}x9y'Z
    free(S.base);
!O"F*I-xM-Z#vO A:o     return 0;(f*hm/LX/vfH
}#W aj4`@Px)R0P R
-c.KKdb
int ClearStack(Stack &S).j PZ&@? |?
{
f1Z[ T4dO&|"Z3CZ+a     S.top=S.base;#L;E4rUwm
    return 0;
"|'rvc2x0O }
{H#W"s|0|6d&gJd +jl)z xb
int GetTop(Stack S,SNode &e)
w!f0J7KWo!{ {:wL~/ez%RR;u
    if(S.top==S.base)R-P/`k5t _,p:^
    {4B$p J.l1~
        printf("栈以为空!");
RVN$s A2{)D         return -1;1lTvl1p,fm
    }6u&y KBz
    e=*(S.top-1);O l8LUYW$TU
    return 0;
ih%t;wJ8KD }
RtIm'K#RZzp dZL /T!\'T7N Lg
int Push(Stack &S,SNode e)6VD1FaP3A/x&QN^
{*]m4n7F:Qi lTD9I
    if(S.top-S.base>=S.size)
sl}O8G&mTxb     {
*` g0b$d+e&Uc         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));-X,[(DJP|"A
        if(S.base==NULL)
0O/t6oKO3q         {BR'h)nA V.A)UtZ wN
            printf("动态分配内存失败!"); o1@ c(n$?e
            return -1;7Z&w kQ f,\!A
        }
i n!xto6b3w         S.top=S.base+S.size;4l8}^2UH7x4]*lT[
        S.size+=APPEND_SIZE;
1xsOU t0G3] F7vYS     }0H^2jC%Ar,xy}
    *S.top=e;
4NMG[+L5]N     S.top++;,v#z3^!h[+Q o
    return 0;-E.j:L}&w3lM4d}f
}
;tI Y)bL"ij8x3K)p
oM:v dcWz int Pop(Stack &S,SNode &e)
l7S k`!T+DaR {"n[)wr h4u%DhN
    if(S.top==S.base) H2l Y H7N&y6B,S?
    {
+r Le.x}5j,A7n#ki         printf("栈为空!");/S(Jk qk/WxQH#i M
        return -1;
br K3H[1MK     }
F hMTMl)V5a     e=*(S.top-1);
z*^? }*T-l     S.top--;[S x0U'Q,P
    return 0;2J _gJA
}Jk8\Y(b/rD.P
4n(o C5x X;kQ[
char get_precede(char s,char c)v/g7o8|fK;As.Z
{
/f9m/A L,B7t-`     switch(s)
Ra E&eR"?     {W`/f$j)^w2Y+k
        case '+':                 
pCp[{2M         case '-':$iL#Dj#AS
             if(c=='+'||c=='-')9dCu r'WkDE
                 return '>'; ~d"Vgfz
             else if(c=='*'||c=='/') Y+d*pZr~
                 return '<';P6ON6rEa
             else if(c=='(')
PlKl!JE(]8y N                  return '<';,T Ug Ug%w
             else if(c==')')
,sf%I)b.X-?                  return '>';{5GJ8G0s+}{9A${*I.v
             else yC@&q"_*w
                 return '>';
sF;BqY^]         case '*':
~Ng;^v         case '/':
HE9Y(Xh]v q              if(c=='+'||c=='-')
-G9SU5fk                  return '>';"nrK:Q,[9E7Yu7r[
             else if(c=='*'||c=='/')wx ]@[$br%g0V
                 return '>';9\%y's"s+ma{4^ }@
             else if(c=='(')
g'mX%?}                  return '<';
.N5v ?9A#Z[q(gG              else if(c==')')j(DQ&q8z5M F,U
                 return '>';s6c!\4` f&qlJ)S
             else
rT)i oEb                  return '>';/JT \nu#Y'T
        case '(':1QB"k.yR4j%C
             if(c=='+'||c=='-')
4u;My#F\Brf(g                  return '<';
/ry7A?6Q!s}*NF:W              else if(c=='*'||c=='/')
U n6o?*l {                  return '<';
Ub\v F+\&a O*g'g              else if(c=='(')R%Bqq |]%rd _d e L/f
                 return '<';lR6N(`*Jy~
             else if(c==')'))bS7eM UnPk3v0b
                 return '=';
&M0c"}0N.}              else
.V"?t"o)QrK                  return 'E';
$t`,\E"W4r%a4I(L         case ')':
0n8Td9Q[)bF']              if(c=='+'||c=='-')0q+iu4}I.}r
                 return '>';2kg/\x Ep2hg w
             else if(c=='*'||c=='/')
Xb.iT3}                  return '>';|/tru&P
             else if(c=='(')(S8g9U*k,n f
                 return 'E';2y"S^ N3P0m
             else if(c==')')
1jA4q h/^+S3D                  return '>';n*? yn%|8{!o,P
             else
+w%U5N#h+n                  return '>';:J,N8];Sf:AwkNO*Q7R"L
        case '#':/Oo cEhgg&o3D H\
             if(c=='+'||c=='-')!b/[w"tZ ]
                 return '<';R;gJ K g0sLJ$v
             else if(c=='*'||c=='/')'U [v Y"]+Lq-?
                 return '<';? KQ2n1X:t
             else if(c=='(')
4sJ\D/Vh;d                  return '<';@K/o2y P1y,C
             else if(c==')')G L%T#n1T6R:_
                 return 'E';/p o*i+E W2n
             else
%yQ}e,F&[mP`(E @                  return '=';M"R#lE"? E e
        default:
H$y @Zj4O@y3T/s              break;9rp~%DZ9n^F
    }
I4LC.m ?p5}     return 0;   
B d4]Nc(H3i }
?RD4LM@ ;@ x5[&?`"z7n
int isOpr(char c)
;?{P U.e;@V;H/d-a {
`I%F8u d x0\}     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
9yW:y@2`6|o.M ZM         return 0;W@7V i&]\~ F
    else
QU6{mW-c,v4C         return 1;
TG1t]:_g }
;~;~ToXJ-H;E W~0e [:B
float operate(float x, char opr, float y)6R2B5N}9lK1`;K
{D t3~4rm
    float result;
(`0A;cO(c     switch (opr)h k@R8I I'KwK
    {
W1Phv1Xq)Shk         case '+':
X P!nP ZE7LBSA              result = x + y;
%Q/_Qma__              break;
1hGH-~` }         case '-':
8`g&M(S0I              result = x - y;oD/y+U&}S5c
             break;lU2Jh&?@w
        case '*': :H ko qLUW _cB?
             result = x * y;
G*Y1@-?1F4_              break;Gb0H,U6Mv.DT
        case '/': b8s V1GK YZG
             if (y == 0)X W*N#MV.iu x {
             {
]!sa.`R                 printf("Divided by zero!\n");dN$mqR4u:y B)z
                return 0;?'W |{Ze7Q(Al
             }
?)g8u[Y7z`B$jw@              else
:nloU$s5Ag&v              {}Da G\8tz
                 result = x / y;
;yQ y0x;@5d                  break;-XB,o&C@
             }]-@&M C O_
       default:
mZ3j+fy*@(D              printf("Bad Input.\n");
5J5x)]6}z2n;C              return 0;;S A]0u7D+L7YO"[
    }
|F QM}|7H*~     return result;;T xES*@h-r$y
}   
s,JS&{so!c4m
r&P!mA] ^h float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
?%[ O'E h {
k*h#dtB#w0TUx4H,WZ     Stack optr,opnd;2yRU Vj-M@J8W
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;W#b LU9^g k
    char c;"Hl6z~l&j ] a~
    char buf[16];EqAEht*[FwR
    int i=0; G,DcU(@ hzG.O
   
@5m F'Uj     InitStack(optr); /*用于寄存运算符*/t1W,n j C0E,t2dx
    InitStack(opnd); /*用于寄存操作数和计算结果*/0d2fR5bp
    memset(buf,0,sizeof(buf));%l?z B5b2n+Z)Q
    U9X z^5f
    printf("Enter your expression:");
6_2n.d"US_V)u          CU i,y8qJ
    opr_in.ch='#';-R*[6M6`\ TCt
    Push(optr,opr_in); /*'#'入栈*/
4DWy1h+}9eq2N     GetTop(optr,opr_top);
(l&IFvke     c=getchar();HrkBJsj
    while(c!='='||opr_top.ch!='#')Z4BF~g7P {
    {TA*lzL
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/8f1H:id*Ed{ |2H'h
        {
'^7}.G^-Na,\)n;S             buf[i]=c;w]m _M)J;q
            i++;
}lz A5`e             c=getchar();'O Z G/Hp'V5l9o3\
        }
8Br-A1p2V$g         else /*是运算符*/w!fTu!K}
        {
L%hu)~0v             buf[i]='\0';
s;Mne,j2O!s:f!\ a             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
Mkv iHdxk u\Y2a             {,ZNc%uj6z-W
                 opn_in.data=(float)atof(buf);+Y XZ{:[3S&\?
                 Push(opnd,opn_in);NryE0_$j
                 printf("opnd入栈:[%f]\n",opn_in.data);j8RM o{4N4i
                 i=0;/E&H d e:A+DL:{],F
                 memset(buf,0,sizeof(buf));
tB~"Tl N             }(US5P&z&p4M7F6G
            opr_in.ch=c; Hx;h&u)Q7Q
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/f.gg[W:s:Y5o
            {gu(uaz4qR @]aeV
                case '<': /*优先级小于栈顶结点,则运算符入栈*/k|8zs:l/iq
                     Push(optr,opr_in);wPM X/@s'^w
                     printf("optr入栈:[%c]\n",opr_in.ch);
$Ywc.| t1yYD                      c=getchar();b.ol:q)p.Rn;zB
                     break;g%mN o;TC,R2LO?
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/M(O@%O-GtFC
                     Pop(optr,e);
5cNL*?ry                      printf("optr出栈:去掉括号\n");:@P&e5@yh(]
                     c=getchar();
'D0wPy"B ~;k                      break;
B*lkeM Ac                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/c.l{au9G2Q,E%Z
                     Pop(optr,opr_t);
KHk$O.x6L                      printf("optr出栈:[%c]\n",opr_t.ch);
,tl ELh*s%f%M]K                      if(Pop(opnd,b)<0)
9XZ(irAMC                      {Gx'rO7F L&[6N
                         printf("Bad Input!\n");
d1[qbzM/l                          fflush(stdin);uu [pe_H6F}
                         return -1; ?6U-f~Y
                     }
TIO[-I7\"`                      printf("opnd出栈:[%f]\n",b.data);&F)?gSRG0yA
                     if(Pop(opnd,a)<0)
gm\B w5i:lP                      {
Ahs{!bv                          printf("Bad Input!\n"); xOaQBNs
                         fflush(stdin); bD(i-lOJJ.R(bSl-p
                         return -1;/ql"u {8IL
                     }
'V@Y_ | p&h,ud)j G                      printf("opnd出栈:[%f]\n",a.data);
xD.b J,l[r                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
C1I Z mu;y d wH x3P                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/8V!X*feti9X;w
                     printf("结果入栈:[%f]\n",opn_tmp.data);
y%K*f1a&q?K                      break;
xm[m @&x             }JjqNI
        }Xy@R'f.d}
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
4|"Q+V^O1b,g#?l2U     }
0F6p I%Cu^%Qi"a     GetTop(opnd,opn_tmp);Tf;S&]k_rJ:e
    DestroyStack(optr);
v%xY c4h"Ga     DestroyStack(opnd); f6E'jc s-B jB;V
    return opn_tmp.data;@#B&h L5J$O
}
C2cOZ+rfFZV;J wx0Hs)u8lih
char *killzero(char *res,float result)
N a/fqo V!GwT de~ {
Qc&z[!tD)t     int i;
8fY*Z eERCL\
6Y-Z3G`3l     sprintf(res,"%f",result);
y#oAC,\S7~|     i=(int)strlen(res)-1;(D6F!h qP [^
    while(i&&res[i]=='0')
ei m!D5? G     {
O/DV$a*J OSoT \         res[i]='\0';
o}@V1pZ5Y u~         i--;
E U!}Bd[we     }r9K@Gy]F:yB$~R
    if(res[i]=='.')ZXg1V9t D1uWi+{9G
        res[i]='\0';2_|b3?}
    return res;
*[L&a|vcJ%D }
Zjcs:?%y ^g 7mg!}.B\JBb.[H
int main()9dP0d/r+l
{
1v?oINa'PfE e     char ch;3r6Z.n!m|o t
    char res[64];:B9w*g n5S"]PEw Y
    float result;m%T/h ]gNc9l
    while(1)
Oz P*w x.Mh}FW!d     {
A.kX5]0l L         result=compute();
a lp,tp{sW         printf("\nThe result is:%s\n",killzero(res,result));
4x+Y'V!g3?O2p         printf("Do you want to continue(y/n)?:") ;
$~]v\YLn         ch=getch(); L+X:Tm |P
        putchar(ch);
F*l}R\.k f(tm(_         if(ch=='n'||ch=='N')p+SZ0u!s([)t
            break;
hH4U }"N5u.w@         else
D8^B*Uh:O,T2\ u T^             system("cls");
(U*G.H$v6qNu     }2oNjjG/J,?
    return 0;/D sf.y(~'S R8Dr
}[/i][/i][/i][/i][/i][/i]
``&T7X7mG(Z ZsiX+H A
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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