捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
J#qC ?C$_ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
w9gwqR6l /**************表达式计算器************/
"TP'SnJx B #include <stdio.h>
s[Ol VQ'a$F5z J #include <stdlib.h>^!`|^O1BH"dj
#include <string.h>4xN\`f0O9O4p
#include <conio.h>
5M#BTA(R #include <malloc.h>,IH9LI:vC

&\5i1@p,[(S,}6Nl #define STACK_SIZE 100!K"?s'|F0Th$N p8N/]
#define APPEND_SIZE 10 F!X wi|

y8f'd'f!GDS5c${ struct SNode{
"W2e_Cz)v q     float data; /*存放操作数或者计算结果*/
:E`l!z|(H v"E t$q     char ch; /*存放运算符*/
%},y0R%y3tva }; nb$n8PR/wz
V2I wD{oQ
struct Stack{
Xk h-@1M v:c     SNode *top;3G"\T6E6K*u Y*i
    SNode *base;
SX4_1R ]/V)]fT[     int size;Xf6N6R~HK)K
};$M0?Up7zI,\
P"M o6ks ]buiE~
/*栈操作函数*/Q a*J2|l]
int InitStack(Stack &S); /*创建栈*/ky8G.h bV"N;K['p"a
int DestroyStack(Stack &S); /*销毁栈*/.RF+S*uj \.~9S
int ClearStack(Stack &S); /*清空栈*/-M)V"Pw)Da5E8R
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
xz?E(@ int Push(Stack &S,SNode e); /*将结点e压入栈*/
%F#gGT _t%[,S{ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/0y!YUgz[&A:_,f
^ A,Cz!m%O+B
/*表达式计算器相关函数*/'@-A-?gO$@D}&A-?R
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
JV4q Id3kn int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/E/\p3lL
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
C8hi[m8Z4mv^T?8~ float compute(); /*表达式结算器主函数*/
-B7L J/kU7l char *killzero(float result); /*去掉结果后面的0*/
*p.TC lLWI.X ~`"?^F
int InitStack(Stack &S) n }0iY1Hx.?
{
`*CFQ8U-a9[     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
K(Cnp"K w){.['M;gv     if(S.base==NULL)
2c6A8cM1BFW     {`x1]KMOv
        printf("动态分配内存失败!");
Zx6vz F6rq         return -1;
2z~5cA3N)?+] J8f     }
dS6zFvI aM     S.top=S.base;u,[7a DM7b1NM
    S.size=STACK_SIZE;S7QhVmA-U
    return 0;
bP@t"J!x1h0} }P"I9E+p9@:mWS*o

q Rs$vk int DestroyStack(Stack &S)#B Fn6q!lg0] u
{4jsNZ(X?4g
    free(S.base);Z2\p7M|\ AC R
    return 0; V3bi]4Z
}3a.r}"c+Rk
&iq,P"s sx
int ClearStack(Stack &S)
'd`'ynt {
0L:ZGs&Iq5J*t]     S.top=S.base;y8H/Ns-~7ko.sO
    return 0;
-iyE/K]1r|]B })cr cb.fi,V(K

h4|8Jf^p int GetTop(Stack S,SNode &e)
kj/C8hR'{ {
,@T K*MK0G,I!A#?:x]     if(S.top==S.base)
@ V*t-p6|J     {P6`y%b:t'U
        printf("栈以为空!");0\i|2@Dl1^lJ
        return -1;
.c-k}$l J/u g4k1y     }
}Os[[]     e=*(S.top-1);#ZY8VXu sP3q'q
    return 0;!u#Un!{lpi.D rh2f
}5ew"L/Q+r k{C
X!c/VV V
int Push(Stack &S,SNode e)VY B T;N5sw
{
){P]{hn     if(S.top-S.base>=S.size)$[5]6S*IYV
    {(|^1oIBW a
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));4w:Uidr,L
        if(S.base==NULL)
T#u.E| B u$pA         {
jo"o H@_tk             printf("动态分配内存失败!");
7}9Q(pv?J'O[             return -1;&\4a bEXw [l
        }
Ucb!C9ae*g1f         S.top=S.base+S.size;[/egY)W(}8}:w9T
        S.size+=APPEND_SIZE;pB/G So
    }
W;o n d9gXs*nm#|1P     *S.top=e;z-M X4R+gp!r%y$QwJ%S
    S.top++;
'I Cz P/VC     return 0;
;L*T@6m C%g+I(Z)z } ]6bB fp

2HV @ ZA int Pop(Stack &S,SNode &e)
S#f&_$k.ET[&j3W#p W {Z.F\7xDQ&m3s@)mg
    if(S.top==S.base)
/U BY2spFN7SQ v     {e7@v \4xq6q|
        printf("栈为空!");
,F%CL0c0r0V         return -1;IV ?'i_(E
    }"N0x#~!K9f3]b
    e=*(S.top-1);0C f$@,S+Q#`y5D
    S.top--;2`'b0? F[^n
    return 0;
^8Au,n+rj }
heE ?e#K H
GKRg!h-^:\4S nXZNe char get_precede(char s,char c)o ]#^ f7B
{!C.TdgM^[+I|
    switch(s)
R{yRRUb1Nr|     {
9V:JD{$ka!I+i         case '+':                 )p$W/[L0L
        case '-':.Z:G"k-MY*a;Y)|L
             if(c=='+'||c=='-')~#y9A4EU];}
                 return '>';
4P2uR8` bX5r9j}*?              else if(c=='*'||c=='/')
/Xi_rm                  return '<';m? gz?r)D
             else if(c=='(')"P$w6Hyi W#R%k f z|
                 return '<';`S&OX2P0y Bl2p
             else if(c==')')p'};~Zo3MC2d"d2O
                 return '>';
[FQb/WN;NdV C:NO x              else
L)k ~#^R{:~9lZ3l                  return '>';&k0i4J1g[{
        case '*':
d `b OL@p         case '/':
z7o,J2f,]Ah)n              if(c=='+'||c=='-')/av dAD_ pL
                 return '>';
K"v-o.lAt y/EW.yy              else if(c=='*'||c=='/')
^|G)j0H-ih                  return '>';
+BN(UsV"r;M5}%iM\              else if(c=='(')
[ ^f+yrVz^S                  return '<';OD0u g@BY
             else if(c==')')Jm` l ^Oz WJ9?
                 return '>'; i4`#dJ v"@*I*c
             else
2DQc6Vl                  return '>';P;?8} gyI&K;N&L n
        case '(':#J m lwQ2g(r
             if(c=='+'||c=='-')
4X6pq&mE                  return '<';
ivk w.itN0F~Jc              else if(c=='*'||c=='/')sk6s;|7tap
                 return '<';
9I~/W-CF:FN7_              else if(c=='(')
@v`qDne?(tw                  return '<';
0e6jS1i#j7um              else if(c==')')X"\ ~/e ]
                 return '=';
Ov(I8S7Uo:A m,I(g              elsed0Hux9?Ye
                 return 'E';'nk3wT2U
        case ')':
;z3J+~5q8@A1f+J+X              if(c=='+'||c=='-')'q GW}%N8u
                 return '>';
Z} Dk~*l(A mCO              else if(c=='*'||c=='/')
9T N.t6F@ A U                  return '>';
(]/R[4Qsp6q)?              else if(c=='(')
{5~)l"SSA5GM                  return 'E';
px H0L7D              else if(c==')')'} ]3T9W3@%{S$U
                 return '>';
7nOm g(e/E!b"UH&N              elsenA5@ K$u:RU _&J'G9|*rP
                 return '>';|Y)H6WwhZ
        case '#':(L&^|D1{M F-]
             if(c=='+'||c=='-')0\OeHxM
                 return '<';j.x]R4C
             else if(c=='*'||c=='/')
z z ?_,w+fI[[                  return '<';3p1CpVS&v#h-h
             else if(c=='(')%FAY!A e)`
                 return '<';
^7D'[ e-T_              else if(c==')')
5Y)bgG5I                  return 'E';^(x~#Q*l K4|3e3AE
             else,sa6U T/GJ1U
                 return '=';
D$sTI&yGGU)^         default:
.D Os/~@_6D              break;
]8ayD/[I#b     }SsXBbLC8n A
    return 0;    xb(W/r$_:}
}MTfam'Ev0inK/?

| YA$Zj"{0e];TPC int isOpr(char c).k"gjbu+a)z.Z
{C@yz4l Ku mJ
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
4~:P6t4g+^         return 0;bjfPgl
    else
+Wi8D ]gj,l;X[         return 1;'W'i$YJp*U
}
$K+Cc#U8db
eVccpMy"|V/t} float operate(float x, char opr, float y)!m#@ \8S6PEGb7ew
{a7Ci+l-jz*O!V:N
    float result;
&I6On4|S;A@$i}     switch (opr)$i ?M/W)[G
    {eA'f ^ [c xE']
        case '+': gyW"c7rT4j-`5i \MS9y4Z
             result = x + y;
Xg SH.C G.P-V              break;
*lnWql.q9TV8a         case '-': 2Di \P;JY
             result = x - y;
#Bi3['oa              break;
Sl1W-P-s1[W         case '*':
"L0qX m)B;}2`3\UI5@              result = x * y;~ ?Gz{k!i u
             break;V1DLxPz+T
        case '/': FFD}VLu y)D U9{
             if (y == 0)y:@IZZ?3O9W
             {
4K?d)q G;d!p                 printf("Divided by zero!\n");%I3SA A\1l
                return 0;
0i6LaK,O4s6y              }
9TH$T[3WUj              else%a0r t!B&Gw~
             {9C*U9hq`
                 result = x / y;4QSV#dB@hB
                 break;
QU d%`v'O B,N0i              }
1O0Ny;?)Wc'L+Z        default:
-[*[8VLySx X7P9I'b              printf("Bad Input.\n"); KKb,S|%o%}
             return 0;_"q1|ex
    }
$VO| U-jsI     return result;lYEQa.R{J
}    ;C rlYe
L$@{/x+N;?`.K V
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/W}TzN~4]P0K
{ Bd%Udh@
    Stack optr,opnd;m+?:q w9c|K:[
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
A)y3l.o X     char c;FC$PU3wm&}
    char buf[16];gxc:b fy ?nX} h
    int i=0;E SL)U+e_1LU`
   
!Ub s z{mq     InitStack(optr); /*用于寄存运算符*/"G#Bq CQ;Q;HQ|
    InitStack(opnd); /*用于寄存操作数和计算结果*/vy:nzZ%T6Ta)J
    memset(buf,0,sizeof(buf));
e+d3iw*G4@    
x9BW |3oiZ     printf("Enter your expression:");-S@2IY [
         JoO(FOFc
    opr_in.ch='#';r)AtN\w4]
    Push(optr,opr_in); /*'#'入栈*/
*V"_6c s-S|ZI     GetTop(optr,opr_top);,Nr J-u4z6q;Yv
    c=getchar();:Ov6~5b'r,sR dR h
    while(c!='='||opr_top.ch!='#')
I$eZ#_.P3w sM,b6|     {
;C\5G7g3[-QD7|V         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/R'L6b'H,S:@,X
        {
2m,b!Zi{8l.R;I%J             buf[i]=c;
Z0y.}c0c#C             i++;4Ca-Ob;lw
            c=getchar();0l A*V{d/Y
        }
~ Wny_ I         else /*是运算符*/
7A"^*}+Levp[N         {m'G6VK,\0I
            buf[i]='\0';\x]%I)|I2x)A;R-FC
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/{m+oI!m)n*B:@ G
            {x&kT fd6aOz
                 opn_in.data=(float)atof(buf); ~ y,\5g,M:Pr7`|
                 Push(opnd,opn_in);_)}S9Q9s_6^$Sr
                 printf("opnd入栈:[%f]\n",opn_in.data);
1H J6bq&zK2~                  i=0;x];\kk"Q9F%`J
                 memset(buf,0,sizeof(buf));
:?J({$b]hu^(h\             }
3MW6^DbB(y[             opr_in.ch=c;
(f L@\.}*sQ             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/!XPZG%UA]Y5t
            {
|p&l L4a[x n                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
:KT2B JT/Hz[%t                      Push(optr,opr_in);
dNP{-V                      printf("optr入栈:[%c]\n",opr_in.ch);
yWVcLmM~                      c=getchar();Xj2U'e$h
                     break;'U vV!I/p
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
B?d'J-Y                      Pop(optr,e);
_9tKZj F/ul                      printf("optr出栈:去掉括号\n");'{mE$}&tD1x
                     c=getchar();
|Cx8eth)r?!l[                      break;
7|:|bJ N"V3e ?%W                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/7j&nLeyG7Kx
                     Pop(optr,opr_t);
m9x7U/O!f                      printf("optr出栈:[%c]\n",opr_t.ch);
)P/wj~@p8rL`'^                      if(Pop(opnd,b)<0)!@p6P\9h9|Jq?
                     {
R0@,v0W/dj4E,W+~                          printf("Bad Input!\n");
Nl0?^;U5e1l                          fflush(stdin);
+G@ r1S5M2s9MDwIJ`                          return -1;
1@y }['[#\V,^V                      } o9E4Jf^
                     printf("opnd出栈:[%f]\n",b.data);
$k8U b)]+E M.w+I                      if(Pop(opnd,a)<0)
@o"Scfz[(x                      {
uz!g0w$o3[L                          printf("Bad Input!\n");#x2a_\g
                         fflush(stdin);
p? aW_(C1I3G                          return -1;
d@ QGqvC                      }0X7D*Tq MM m}!f
                     printf("opnd出栈:[%f]\n",a.data);WA}L'B o ]u
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/uN H;JpG,R[t
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/)cOr!iFB8A9V
                     printf("结果入栈:[%f]\n",opn_tmp.data);DY0B7l;~~
                     break;KT&{$o'iS V
            }AvZ,H'G-jYI$} d
        }
"e E2Ro_Z|"X(F jP1h         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                D%v8NJ7A EG3TI
    }
%s(A$hIq0J     GetTop(opnd,opn_tmp);
S^ pE'G4Cc     DestroyStack(optr);Eu2r/iz.X3B[
    DestroyStack(opnd);/vi A2x5`T+\ m+Inc&h
    return opn_tmp.data;?bq;Adt|A
}j|4S|`;l,Z
+] rb\(Z
char *killzero(char *res,float result)
${\8X|lq!c {
@ rj2Ffb` G l oE     int i;/|o(H)_f;w!s
Tj V2cv3A` NU
    sprintf(res,"%f",result);
\L*H nP:h:j     i=(int)strlen(res)-1;
!Y0J.i7A'L&oO?w{6Su S     while(i&&res[i]=='0')sst1k0i8r'e@
    {
?9w3J+^5WU)]z         res[i]='\0';
)k5nZG+\a\4n:A$Lw         i--;
0C2GZ;t M~!m3`1V     }U+v}as-P)N5~
    if(res[i]=='.')
:D|m2Yq7Le         res[i]='\0';|:z]?Fh9I"@p
    return res;
/J%^)o)Qy&r!IT R }
2D(Smz!B3t'k2W7H $y5B.L%sn-J
int main()@RXYKN5nK
{
y-r~.`5i VT%?     char ch;
Dtk&Q2_iK)i     char res[64];1C&m {hr1y.wl+S6F
    float result;
a?*B:p-a.\k/u!n     while(1)(\+mb+I(iF g"@
    {?u&X;?-U5e.F n h
        result=compute();7\!x ~;tI@7z\Zm'R
        printf("\nThe result is:%s\n",killzero(res,result));
!\|`B*l&S/s2N         printf("Do you want to continue(y/n)?:") ;D5M\I$UW
        ch=getch();1bN/OuT:l
        putchar(ch);6lA0`M r @G!J `J
        if(ch=='n'||ch=='N')2~eiNNN2d4kc H u
            break;
C,I0u&op"S         elsew.wA9M%@f
            system("cls");
H"_X~8z     } a _k ^7f{T8n
    return 0;v%J I T ii-U$rj N w
}[/i][/i][/i][/i][/i][/i]
9Th |@ ~B+V mp6?4GX;Y
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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