捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.2v0l)o Un-s
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=i(N+Oo D
/**************表达式计算器************/:B%\2U%k8i-U
#include <stdio.h>
.F1\ uOv3Ks-A #include <stdlib.h>"B9i5L5QD+W*b-cW pNB
#include <string.h> @!E%xc*be
#include <conio.h>
evQ,R;n&x #include <malloc.h> _&t[E i s @*m!L

!|n?9lPa #define STACK_SIZE 100
iJ Rw O?6I\ #define APPEND_SIZE 105^~'}8B@z9~;x

T[Yd6^'K struct SNode{
p4XS"w,R8J0D:\     float data; /*存放操作数或者计算结果*/
s6l]8{#N1Z8i     char ch; /*存放运算符*/5};U/T^/EJ6Ln~2m
};)b y [_Jp9x
R"vn)U GX^
struct Stack{
B!RmQB^P:O"S5L     SNode *top;0s?1fc ]T:Xp/c
    SNode *base;$P+iY5B7SB?Z
    int size;
x+Cpp*h RTT |,t };
W R%_\,L/Mx
td\(M4t)XsoHel /*栈操作函数*/![7FdFh+B [BT0U
int InitStack(Stack &S); /*创建栈*/
)y su:X c:p:q int DestroyStack(Stack &S); /*销毁栈*/
Y1F9U't$Fs int ClearStack(Stack &S); /*清空栈*/
f!w5X7ZN8R s)E#Q7{ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7?D/v#d'p zZ}8Q
int Push(Stack &S,SNode e); /*将结点e压入栈*/HN{3l)v-E~
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
k/H0O z#Q:lg ` 5H)h7Vn1pII g0n
/*表达式计算器相关函数*/
+AQe5LE char get_precede(char s,char c); /*判断运算符s和c的优先级*/R#J!\k!}"T5H6} k
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
Bt)N(x1F!ri^-S2c+F float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
#L!p9}_Oqn0a9j float compute(); /*表达式结算器主函数*/4sR{,pN7c"i
char *killzero(float result); /*去掉结果后面的0*/
7tX-v _qyi!Z
$q6Y/e/\ U9i)T-N Rjc int InitStack(Stack &S) g D$P-a*\{g ]4F)^
{;s9wM!M |
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));iwf5ex!]/bO
    if(S.base==NULL)[*}h6T C
    {
*u/T"I5W|d-f.?         printf("动态分配内存失败!");;HL BO7LvrB
        return -1;
Fm![?3_L OG     }
)}eRZp+}i     S.top=S.base;
UU(^!Q]7i0M     S.size=STACK_SIZE;/I q+AV_8{b
    return 0;
3d:Z"DD;@r7zq }
|4x-J2M5`2hI^Xq
^UQ8].Fff int DestroyStack(Stack &S)
i1DX9a$o q4s {
3_s/b2P!A/EjJ     free(S.base);
s,f6Cd4i Lq.d     return 0;
ooH,MVB@0{+M/~ }
FO5|,J3Y
q)j;IQ _ C @ @ int ClearStack(Stack &S)
!_$v&ysE \)G {F~~ u$s9H^Qp
    S.top=S.base;0nyR3tZ#A$NK
    return 0;
jh7K!O(C5d0@ }-r"Co"D}4Y#i

3T~4UHd"nW int GetTop(Stack S,SNode &e);F3R{ d+{}v
{z$PPav+Yn%g
    if(S.top==S.base)
/V&j3gJoS@*F     {
Y s;OX)mH         printf("栈以为空!");e6h R9uZu!{ \
        return -1;
u"r@,k6F%[9B     }P/wG2h'IsZ,_%^
    e=*(S.top-1);
pO;gsY&L     return 0;wsd)_FU~:y
}
!W!d^4zU:UT|
9?_Snl[,J&j int Push(Stack &S,SNode e)+n/X.f,bZEg
{5pvEjD4X
    if(S.top-S.base>=S.size)
N9Cf Y6I{hTY     {OV-Bcqf#U
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
W t7q.MX7Y/D9K         if(S.base==NULL)
F?sDy)?K/L         {
&dM E^y-VJ:X             printf("动态分配内存失败!");1U3^ H!M_)c!o @
            return -1;
%P7S[*uG'D'`bopQ         }
$I+i+Y5N:o         S.top=S.base+S.size; m`'vG"~.zL&P
        S.size+=APPEND_SIZE;
MHM&fK4KK#Z9~     }
0q0W q| r^     *S.top=e;$Q Vs,xi W JbZ
    S.top++;
UR{h+o?y     return 0;
7xK PZK#i9h-kkr;uI }A|?;r^KmC1C3U
(x{3g@,h4},]n
int Pop(Stack &S,SNode &e)
D.V \vJ __ {
ly,h y1g%t(Q     if(S.top==S.base)
8B0V} r!R~3W$|/F     {6TF/s"X)a]Q4pu6s
        printf("栈为空!");;`w h IaU5M-CQ*V
        return -1; M IXO f e1ub!l;[)Y
    }0a N5Ku4?+N
    e=*(S.top-1);
0yb)Ae&x|'H d     S.top--;
!k!]XH/K7]X     return 0;
%X*X3i@K\ } Jd2R!ay+s8mB{

Y4D#^[ } R.l.? H char get_precede(char s,char c)
,YXk^R#M!A {
&FWUY/L9Y8@@     switch(s)
{2TV9nD|     {
*u@ J0XP%b5~*R@         case '+':                 ^3w Bpn XX&P4X Z L
        case '-':
"jZ9nY1SY L              if(c=='+'||c=='-')
js!Nl{zi }7h3Fb)T                  return '>';
XtG^E@\}|              else if(c=='*'||c=='/')J F7U'Z_O
                 return '<';#i;yi!~"U4c
             else if(c=='(')
R a/C:MI}                  return '<';
3O|Z*b*n(aO$G              else if(c==')')
#p5@0w u,@ |d:F                  return '>';
3`W&db4n|d3J!q              else
w_ sH6p(f${cR                  return '>';#z.rN-~g[
        case '*': lL|7}V
        case '/':6WbI peg&s5W l
             if(c=='+'||c=='-')
$n%sB+Uz6e8I                  return '>';
&WIP'w"w:gS:N N              else if(c=='*'||c=='/'))pr \MZ:[tVSO
                 return '>';
7I ]"K6VN.Q)q&`P6Q3l              else if(c=='(')
:ML-dV8C I U8o~wMU                  return '<';_ Dj~&sU[
             else if(c==')') }lR#o,X]-id
                 return '>';
7vF)OD khe,w(C']              elseWp&W+r C6J.]&lpK
                 return '>';SV:MgU_J
        case '(': KJ.cEOL%ifj
             if(c=='+'||c=='-')FW+Q*G3G iCVm@A
                 return '<';
w"? y+i`L              else if(c=='*'||c=='/')
,hL"xewmL1U                  return '<';
O1i9x(|$KU1B'D8l,m              else if(c=='(')
0E8h2q+f.E4f(F3\                  return '<';A6a KSn/X@n
             else if(c==')')
+TQ Lee t2p+|                  return '=';
2tw8X%Q4hg#F              else
j-k {$wb+m(?!D)t;d                  return 'E';
Kjm.C Z` is!E;J         case ')':&m#t\8b@ _'U
             if(c=='+'||c=='-')
r!{ Z2z f                  return '>';
8s'~(E:ss%K}#H              else if(c=='*'||c=='/')Vl~s2z+K/dy
                 return '>';
^#\?&n9k&M:Ik'N              else if(c=='(')
}*_g9yw \(mR                  return 'E';v{2gce x2v/a
             else if(c==')')
Z]Ao7U                  return '>';
C(@c [8G;J*zx              else
U!m*xJ9WH8r!Bi                  return '>';u;]c)eny
        case '#':og,Oet}t1z%t
             if(c=='+'||c=='-')Bf?e&m*_3S)N
                 return '<';
/Qnv bhc/R T              else if(c=='*'||c=='/')*c-p._+rCk"us)J
                 return '<';Yu HntM.Q
             else if(c=='(')5]'Jl"~d {4J:Qc
                 return '<';)^u'orL.rZ'n BB.Q"_
             else if(c==')')
EC+DB/e*o                  return 'E';}~Sf&o
             else%R8c.dIp A ak"l
                 return '='; v+v#R}A+h
        default:6L~\D;[8em
             break;
-fnM Z1yqN     }
!i)g2p'[)EMU n     return 0;   
C2D:m Ne5{ }$W Ve/fX WN"Q

^NO%m*BwbN int isOpr(char c)
l}.p(n%] C#qly {
:KPz)] _,|5@7K     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
Zq*ZQ~S4C [?9O%m         return 0;
,IOD$aY Gr!E     else
\7cfd+~PN3d,D         return 1;
:e#y;k$S'd{ t0| }
O,`q#Zjn%J
Gt3Ov#i float operate(float x, char opr, float y) [e8{ N,w\O;a
{)j-S9{ e g|utF
    float result;bl|`a4q8G;V*G
    switch (opr)
d.@8_2cD+}     {+LYs4E5HIa$s
        case '+': 5ZQo;L)bEbJ
             result = x + y;2|9W-?XM@3i
             break;
(` Vk2^!v@,i         case '-':
[5? VZ"X8W%_8Z              result = x - y;Z\+R'f} v'W
             break;
+d]LSw-A         case '*':
-^a1_/j.SnT              result = x * y;
&F[4q} ~-^)b              break;
6q7{6h/\ f-pBJ{k         case '/': fM+x*H?MH[0X#i/g
             if (y == 0)
&V.jpn4d              {M6@H JW[ ]m6a%pM
                printf("Divided by zero!\n");3uo/Ylqf/|F
                return 0;
o.eA8F;V-Z              }
af&K ?jH              else)O n*\7oG2ZU
             {
!|m4{ l @1^uKw\                  result = x / y;+fU3TlCI,w-MA
                 break;8B{,f9b4C,Z1E9N
             }
:Lc:@)p4k4L        default:
S.K$}-{ r6a+n              printf("Bad Input.\n");
p7U@ r+\ a'DC9Z(G              return 0;1GVbU"OOs|.^
    }gNYR1{9`
    return result;
S QA*M+h }   
]uO\ | a;RI+RU
mVV1nWN3U&q ^ Q;q float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/+m}8Lvn7}E
{ hk{`4Qx
    Stack optr,opnd;"W2K*uxmq{
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;7jV+Z/m1M2L
    char c;
!V3vFhV     char buf[16];^1YkR`q
    int i=0;u uf&h+p
    "OQLM'P7uU_
    InitStack(optr); /*用于寄存运算符*/
yo'IZ0IM$os     InitStack(opnd); /*用于寄存操作数和计算结果*/rQ3VjQ2na:B0G
    memset(buf,0,sizeof(buf));^ zRe%g+eM(B
   
t%c SBQF+BO     printf("Enter your expression:");&`A:O'N)YF!cc6A^
        
4t/nKaSQ7G*k     opr_in.ch='#';)k~.{ l8~4\"J
    Push(optr,opr_in); /*'#'入栈*/
&T9n(\)| d7I\     GetTop(optr,opr_top);&j7v,^%_4n X'{Q
    c=getchar();{0P/h$F5C
    while(c!='='||opr_top.ch!='#')
#[7T r2q(xA!w     {
]W3k7? [QNq vL         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/*}|(b bO;z
        {
't*NT7f;}{ k             buf[i]=c;-qf+Cdsd7t
            i++;9mVG~;W%V kbo V\F
            c=getchar();[4zu8@'V#g
        }2@PczEb ~5`0a,y:Y){
        else /*是运算符*/
ahE6h B']F%Lm         {~ ~g8x Hy D
            buf[i]='\0';
-Nv mC%LS!CF2`#{4m             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/z;W!l,t$m m6Xm8@!s
            {
)\fXt'K B$w-Z1i                  opn_in.data=(float)atof(buf);_4R'B Q|
                 Push(opnd,opn_in);
` y9S@%@oE1G                  printf("opnd入栈:[%f]\n",opn_in.data);v$i{y6^ aP
                 i=0;N7W m _-@ z0h)h
                 memset(buf,0,sizeof(buf));'e uaH4|b sn
            }
)V+Q/u\/Ml,s             opr_in.ch=c;IA`0L}W,Z_ Z
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/#n^NJPq/T
            {${k i \h6nQF
                case '<': /*优先级小于栈顶结点,则运算符入栈*/#U ~.ao7z,Y
                     Push(optr,opr_in);m%w5nrz_'X
                     printf("optr入栈:[%c]\n",opr_in.ch);
xw0Y-lw;E#d7I                      c=getchar();
N;CI d3JR1_)M)o8y                      break;
fRl9A/~(l2b(D [                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/;s\m/o^~&NU
                     Pop(optr,e);
3zC|7z3[P,vGD                      printf("optr出栈:去掉括号\n"); f6B.l(d`|
                     c=getchar();*`3L7h,R| b
                     break;6A{ Wedg4f^$Dk3u
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
5`L`L&R3I u c                      Pop(optr,opr_t);Ea~blG,v6u
                     printf("optr出栈:[%c]\n",opr_t.ch);
\+bdg#p e\QwI                      if(Pop(opnd,b)<0)
%lvZ8HsOaa                      {
$Pvl glyk                          printf("Bad Input!\n"); I K0W.{ [Wx ]
                         fflush(stdin);
C7G5N-Pzo6N&][ @o                          return -1;!\z@[B'P+Z
                     }
aSfA O1t                      printf("opnd出栈:[%f]\n",b.data);!B2`Tzk6C G
                     if(Pop(opnd,a)<0),YY"`$F/~f3Xk&L
                     {t.u;Z od-VKG"b
                         printf("Bad Input!\n");;U#~iqyc5@%H
                         fflush(stdin);!zUk0sA+yul-^
                         return -1;
vt*X%g O                      }Dj&VK TW$V
                     printf("opnd出栈:[%f]\n",a.data);6f#y rR5qP
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/,ZsyU(W
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
G:e'm4hX5I@                      printf("结果入栈:[%f]\n",opn_tmp.data);
aG%?JM\? s*d b                      break;
3U'fE8{OBfn V;Jj             }
J/Az)?,Vm/U         }qR;Vf*Pyxkp
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                g/r tb)K
    }
W(vb j,ULTlU     GetTop(opnd,opn_tmp);
_)f;Ie%X(j     DestroyStack(optr);6bIDt!q!{
    DestroyStack(opnd);
i]2b1S]$PL|     return opn_tmp.data;FrF?o3`
}
*Z6w!N Q[x z Xr@3Ua+d$D
char *killzero(char *res,float result)[M`3ID0Asv
{2pf]%sB9R'?8Q^ `5c
    int i;
\uk XQ)vg]| W/E/sjkp k wc)V
    sprintf(res,"%f",result);2yb p#]bn
    i=(int)strlen(res)-1;0aS#sxq4L/N
    while(i&&res[i]=='0')
a kz o(O;K A     {0] R Q*r^ I
        res[i]='\0';
|5R/~:UawY         i--; ~6x%o2X5wG xX`
    }8n |?8e)ZA
    if(res[i]=='.') fw$iFp8K t c
        res[i]='\0';P*B.G;H$G})[0lP-R
    return res;
4[O NDB&H'Z3? }\.I [CT
0_UP4j2~S9}5?)K#w)~
int main()`_(Jl%Z |dLX q c
{9c8u#v]V X'D
    char ch;Z['hS'I%r V4@o.y
    char res[64];
:CR7D0l.jh5frps     float result; ~!g.T#@ed%G(Y+^
    while(1)
VM(^9fi&T%`R%~/YO     {N5DP2Ej&T"O
        result=compute();
U3W.G p:Am         printf("\nThe result is:%s\n",killzero(res,result));
^Lz5x w? Y^/|         printf("Do you want to continue(y/n)?:") ;
:Fz)G[*Gkn         ch=getch();:P.kq.`zz
        putchar(ch);`ocJ5^ e4t*J2V:I.N
        if(ch=='n'||ch=='N')
yz+DSn5U&~             break;
dNM9]{ wP H         else
7[w jW__-??             system("cls");
'T,j2L gV^ k     }
s2n9N~ J_h@     return 0;3^ @_1UT-vXx9z
}[/i][/i][/i][/i][/i][/i]
o,m6cDQ b[9n(s 3m5R;^tO(z!H]v
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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