捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.Hd_` S
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
d$s(i8V)_ /**************表达式计算器************/6A*b*?-T;@JuH2? H
#include <stdio.h>
%j-c;]6{B8E\ #include <stdlib.h>
+A)~A'L0irt #include <string.h>
.s$`O o dR1{L #include <conio.h> a N#i gf
#include <malloc.h>
W4ob*hzg3c
.[#z:Si8B g9T_| #define STACK_SIZE 100vG!H7Jon
#define APPEND_SIZE 104_l.e{_?
s9s|J L Z
struct SNode{:qV1S|-XE e9g;s h M3a
    float data; /*存放操作数或者计算结果*/+?Pm\9p5Np
    char ch; /*存放运算符*/*?6I2Q[KdyES
};
hea_$W"Oo^a 2q Mc Y5\?8{iPSgO
struct Stack{
Iz|7n7Qxz-t/_     SNode *top;
$k_7tD9A5[5s u%v     SNode *base;` tm,r@2`'Bf B}
    int size;e"Vp?6Z6c
};1q U.^/O2?

7V6_\D$F /*栈操作函数*/T.Pejm I
int InitStack(Stack &S); /*创建栈*/[&~0?+q3D3j
int DestroyStack(Stack &S); /*销毁栈*/
NFlC1C int ClearStack(Stack &S); /*清空栈*/P7p,[Rt#xY
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
8q3A5V5D%pJc int Push(Stack &S,SNode e); /*将结点e压入栈*/bE [ G-FK
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
fUkj.@ n*jP {%rUf/T
/*表达式计算器相关函数*/ Y-AB:X^@N
char get_precede(char s,char c); /*判断运算符s和c的优先级*/x6AS*i}"m
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/4A!Z Te;`#aSmYy
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
,]P&yj ^U float compute(); /*表达式结算器主函数*/
{5ZnEVcZ char *killzero(float result); /*去掉结果后面的0*/
5]fho@zx;l#I w :[9z H$^U%zo4P2G9|0u
int InitStack(Stack &S)
q~0m8x h9@p&MP {
Cz.a*Y"j zU/Wx     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
eVu4q#B+ETI,D'z4F     if(S.base==NULL)
+~O U~+d2`u     {e%K:g!{'DEQ N
        printf("动态分配内存失败!");
{-Al}3CS!cC1l-Q3h G         return -1;%?p2g(@:mG
    }!@/Kxa$d"}"W
    S.top=S.base;?4~5rx"{:Zd wN
    S.size=STACK_SIZE;'^|n5I+TlBAB v%Qlb
    return 0;!~ R2e3_t}5?4Iv
}
!a$I@c0v
.y.IMF8tkA;E int DestroyStack(Stack &S)xJw!Q_ Ubg
{
c]Xi+W N     free(S.base);(p,v"O~c}8F
    return 0; d'@"G SzQ&J2}I
}
ct"ZH+w$j.fU
L8P h QP int ClearStack(Stack &S)
R)x6X5X6{#oM;[M {(O7r!@BK@%h*I
    S.top=S.base;.K{|#P6K8S~'{3d_
    return 0;.X0~/N^-y/K`&[
}
(VdF@ A}O?z
2@X&v'@N.NS int GetTop(Stack S,SNode &e) K4X$X+U W:qG
{
|E.P^ S3y#@     if(S.top==S.base)
!F;nmE%vE{0[     {|5bes_Y!fE2v
        printf("栈以为空!");&xoqq `L
        return -1;o(S&sL I
    }
Tb3xJ m"N:_     e=*(S.top-1);z;RP)kPz
    return 0;
'X1p y!aqUZJ'P }V/N/T)C#U!z

$q] B6J3u3l3F int Push(Stack &S,SNode e)
%Y)z"D:A pW%WlL {,`#rJjq+jl"q6G p
    if(S.top-S.base>=S.size))`.W;p)yZ
    {
g$v9f.h @IXN!@CA%^ w         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
~"a}3C3cB         if(S.base==NULL)
`1ih2x6Ob~`)A         { ]2] W7N mb afs7e
            printf("动态分配内存失败!");,l%Jz_Z'DQ
            return -1;
"aE-R~#N+u$q         }p2{5Z.]Sw!e0rS O
        S.top=S.base+S.size;Ai X$N'qC
        S.size+=APPEND_SIZE;fU sw-OBs)\/u
    }an2YY4A3G
    *S.top=e;#b[zce
    S.top++;MfI\m1fwC2}
    return 0;W)]8c Znrk`
}3lNM;m7W

5mD#sm,KV0FQ(t int Pop(Stack &S,SNode &e) }ZbMw
{(bo1{9w%qi{)uv6C
    if(S.top==S.base)
&N;c:P4S c&v}DH \s     {
Or`h.H/JD#B         printf("栈为空!");
bd | t OH1~         return -1;:HxV/J#[v]6X
    }3R4TH.q,G9gg D
    e=*(S.top-1);uJgTG$G
    S.top--;$~YV$B AI
    return 0;:S0^_'a*D^-Q
}
#k:LZi h_ 3rs2]'|8\xu1A!r
char get_precede(char s,char c)
!d0tw5Zmk }9\ {
{-]va;s:U     switch(s)
&Zzk| t*E#h{[     {3j7ud$J x(Q4s#FZ
        case '+':                 ,y o+DF I7a-{E
        case '-':
O&?aI2|I              if(c=='+'||c=='-')
1z?Pjn7d'I$p                  return '>';
}ax x,_-U2\i)Ux              else if(c=='*'||c=='/')
:~H-G.@u%z                  return '<';
?/Gt I.Fs              else if(c=='(')
5uSY g}}y&u                  return '<';m}a8fV%YW
             else if(c==')')
{^^"|%V4Q _;^                  return '>';
O$|D \4u h;a+Ef+ZP              else .}es({ ce1y!{2^l
                 return '>'; b7S]s h1b3C"l2h
        case '*':JX@#Gg+_
        case '/':VqEnl nT
             if(c=='+'||c=='-')
JOt/i#g0^6V                  return '>';&f)]+nBj
             else if(c=='*'||c=='/') p^/A!f6pK$_/l+P's,M
                 return '>';+D&\*Nn:aW%h`
             else if(c=='(') ViiPwe.j4Y|x
                 return '<';
~M#^ X'I              else if(c==')')`2hF;j@8\ R(kja/C
                 return '>';
h2j Q!J5T{              else
y&C^tt:n^$j                  return '>';;f|-]-y(_ FhfB|
        case '(':
t&v3u,o+j$MJm5{              if(c=='+'||c=='-')
v v/K4`g L                  return '<';
3V(^Mu7Mw8l%V8@              else if(c=='*'||c=='/')
Cq4U L p1sa                  return '<';3i E B"u~
             else if(c=='(')7m\3bMwz[&j
                 return '<';
7L$}7[ c8dmO{B              else if(c==')')8D-Ft)G&Ea]
                 return '=';
+^/b+GRa)A {u@ e L              else
9sR2Zq| vBH H                  return 'E'; D3wpv ]P)q
        case ')':k/OuUJ`0c6s-Lb Ph H
             if(c=='+'||c=='-')
t8~W J.Y8B!x#r                  return '>';z\ }tkI+X$n(` u q
             else if(c=='*'||c=='/')\QV h(o r J{l
                 return '>';
3I$LaUm]&@              else if(c=='(')
m%@\.uo,z                  return 'E';1a;T._`6Wc1w
             else if(c==')')}-N-e"m2cE!G8W
                 return '>';R'@ u*g i
             elsep'y0O ^ H(?
                 return '>';,_E.Fz!y
        case '#':\ ^G1}DZ G
             if(c=='+'||c=='-')
2T:?|;@m"Sb                  return '<';Sj#K-e2Ph
             else if(c=='*'||c=='/')
O)s1@6n#Mf*~:PZ                  return '<';[x9x5N.dm9z
             else if(c=='(')[)c }.^pV6D
                 return '<';~PO#r k j+g
             else if(c==')')Qjdy}*t~/m3^(\n
                 return 'E';N7i#NHh/b6Ga,H
             else
R}\+E B o-V4bE8\                  return '=';'CYV|SzlW${6W-l
        default:
Q!U&b N-dM@_ r              break;
4Rme6u,S$VZ&E     }S-L k4w^1V
    return 0;    z?!qWEH7P
}Uj:u\`5mi#t

3K&U8^;j*X int isOpr(char c)
$HCCq ^7`*L [ {
^``B1tk/g     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
bx5b*K `R"s         return 0;-c#j0KFE|G$M
    else $NX}qhU)m-mc
        return 1;
5\l X g m8Q9I }
u"B6\S}
w;~Yc'Y/xY%U float operate(float x, char opr, float y)
:`Z-ms7eO5JSN { y/ri3}7r@)c
    float result;
Bt2{fVc'H     switch (opr)
!X"F:a/P+b q%l     {7ku ] m h@%N
        case '+': } Q2f rC/jb:cd oC
             result = x + y;9m_3aP2ay;@
             break;
3Y;d&F;@^7pV         case '-': #{#G3u.Qa%vG
             result = x - y;
"@;]t4}?,V(L.t0S              break;cU8Mw-Cd5vW'ae
        case '*':
N,@$V5sP%i}              result = x * y;
9@r6GX.d!n tM              break;5?@ Bo,v+EK-{(y
        case '/': cw7Y)kV
             if (y == 0)'E6~;E o9} _+?MP
             {
'byH6y2r5h o l7q                 printf("Divided by zero!\n");:i H.xnc;z
                return 0;
yL/z"VJK              }
x`2FS;C              elseJ)Q8\:_ ov R Ns
             {
mRM3vK(x                  result = x / y;T1W;t"y/E*dHz
                 break;
m+M$]j,U              }
-DM5L*G_ \        default:
}(X%ZyBA2c              printf("Bad Input.\n");
'qvH-tVw,T W              return 0;Jmjs8i5G0a
    }T9G;q+Huu]
    return result;Om f rW/h,K#a"R
}    ZUE0NJ(e fH VU

6\@}A7@8eay(L float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/_z1Xml
{6]:g)SxHc$j
    Stack optr,opnd;N \%k#FT+p
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
];FnDo3a1x     char c;f0J+[8O |0I
    char buf[16];
{q*O;}oy#?k:`v     int i=0;d IO0`'A!M/U7z }.Y
    g!_H'cT3}
    InitStack(optr); /*用于寄存运算符*/
h%ZO"S} p6~zl7C     InitStack(opnd); /*用于寄存操作数和计算结果*/
B2R+ndO&b@!Z\#E3wI     memset(buf,0,sizeof(buf));
'EfG[s%]c    
ZM `!YM!R     printf("Enter your expression:");
9X*H:|yyf3q         
`/rJv(J"^C     opr_in.ch='#';7v_f-y2_\3GU
    Push(optr,opr_in); /*'#'入栈*/
9w2plQH ?bJ     GetTop(optr,opr_top); Q)Lg {3Z
    c=getchar();
*r,S,A`r P'X     while(c!='='||opr_top.ch!='#')] Ge,B4R5{^A&B
    {
0E1d4M/l'J{9U/F.f5k5d         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/^!Dm5?#M
        {F3MEP7n%B~$|-H
            buf[i]=c;
!_[xa h             i++;
!EL5C\LC E_             c=getchar();'o^,W9}/xvD }6G
        }
%SUHz6Q[Xs(A         else /*是运算符*/ kF-D4A O5u;i7~
        {
n-L;E%K@I7T             buf[i]='\0';
J XeGM-?vXjB             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
O KJ$x4RS9o)BO             {;L0_Z-y.p*fw(x1ZFd
                 opn_in.data=(float)atof(buf);r3I(k j2m(V z
                 Push(opnd,opn_in);+W}*fN)t[ ts
                 printf("opnd入栈:[%f]\n",opn_in.data);0N i w D%A1FQ2RS
                 i=0;5k+Ypg7`!B mn+K
                 memset(buf,0,sizeof(buf));T6I\ {s;x
            }&Pq%B"ZI%^lG0V
            opr_in.ch=c;
;A j9tA6poi             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
^5Mp.IMa0Mt(R l8G             {
.ev$qd0o7^%L                 case '<': /*优先级小于栈顶结点,则运算符入栈*/6u#D9LS.eC w
                     Push(optr,opr_in);
5PX_j.M:|4d_                      printf("optr入栈:[%c]\n",opr_in.ch); z#S#e xr)c#q$j
                     c=getchar();0K2CXz%KN
                     break;~ ZO BaEt_5D
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/.vPJ&a Q
                     Pop(optr,e);|X3tc.h\_dj%Tt
                     printf("optr出栈:去掉括号\n");
4Ct.Y P5`{\6Cu                      c=getchar();BH0@/BcX RY
                     break;
%AJ,jvN m                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
8B(C{.M6B,Il                      Pop(optr,opr_t);8z&k%S H \(h+A
                     printf("optr出栈:[%c]\n",opr_t.ch);:TF AW_,Cc @.Iz
                     if(Pop(opnd,b)<0);ob;VF^Rq
                     {
&zyrTZH%a v                          printf("Bad Input!\n");
wG*W:X,rp!KZ}u.XB                          fflush(stdin);
dp6u"b;Ke[w                          return -1;$|7caY*V3_c)~Qc
                     }3}%E6K.q-IN'X
                     printf("opnd出栈:[%f]\n",b.data); V#oD3ot
                     if(Pop(opnd,a)<0)2~ ?C W N({V
                     { u| @g!s,[5u1D1A)M(U
                         printf("Bad Input!\n");"Q;Iw2D g-|kc8H M
                         fflush(stdin);
9x"Og Tu1u                          return -1;
*]'L8[#@ Lrd A3g}                      }
"N/@,[z'a0N                      printf("opnd出栈:[%f]\n",a.data);
3S/pH7M(@P4Q)p%A@                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/p@ |%Df cA
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
t8R5E/[Z-O5Q                      printf("结果入栈:[%f]\n",opn_tmp.data); `w5pOu.Yd)w
                     break;:gfWp f
            }"V|`^-MN"E
        }^#\9A%m'tI%j8v
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                bI&D7AG5R
    }
4A5_V9A7[&]P|+W T     GetTop(opnd,opn_tmp);
/]9QfWMA6~     DestroyStack(optr);
k_@tHn     DestroyStack(opnd);0SZg^(h ~
    return opn_tmp.data;!mR"sEg0e;Rj
} WJqm0M)i(B/I|t2i

U$n8W!^B&e6B char *killzero(char *res,float result)|*K Ue)m2Bq!c$S
{#`0Zh6]!u
    int i;
#~ o'^,I(IA3\ _:u*WEjk
    sprintf(res,"%f",result);h3P*V{ g7t
    i=(int)strlen(res)-1;+d h8p;l{
    while(i&&res[i]=='0')R t6x,N)g/H X
    {p&egQM.n@P
        res[i]='\0';
,]q*q\,L4pkx-b'IW         i--;6{F f4tQj
    })z+EUsJ)y
    if(res[i]=='.')_~.@Q{6F6I:Z
        res[i]='\0';At:E~q xx
    return res;+o r yRk/K6I
};`!@p$vY2j

V*l%p`$@ int main()
;md.a7PvK3k^Tj {
7?y$vb&uD[     char ch;
ID4l9K}3^#~'l     char res[64];!MNU-S.@*j N/r8c
    float result;*N/B c-^0L#C O
    while(1)|-QJpimW+w,~O{\
    {a1{ W ~*|!p(r v5i
        result=compute();
s&h!LS/]7s$Dc P]0?         printf("\nThe result is:%s\n",killzero(res,result));
8I[Js`P9H         printf("Do you want to continue(y/n)?:") ;$QLVkG*s VB9bSSB
        ch=getch();
q.u,aR%QF \(F         putchar(ch);
(m7y/nz'Dfg Sbp         if(ch=='n'||ch=='N')%b){2\_/] _
            break;+n2}(h3})g \ e
        else!N~,{`7qY3OA
            system("cls");$C9X(~WK c9s
    }
RQ\0f K     return 0;7I.Jnh3qy0aD
}[/i][/i][/i][/i][/i][/i]i?J"F~^2l]FV
pf.a [&B\8fJ
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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