捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
W Uc)s3uF;d 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
4u)m$@ G/m7Kp(q(H!k,EWE /**************表达式计算器************/8B&c/Q.KX;G0Q
#include <stdio.h>
CT9[?E.Jp"z)Ge:} #include <stdlib.h>
(s.y:myT6R)T%R k'RS #include <string.h>W"Oe g L\,wwe_Oc
#include <conio.h>
gb ~3J%C0F4x0h v #include <malloc.h>
Ts7NU4Ut0w
h] Z$t%r R \6c/O #define STACK_SIZE 100
U Q8Lf?dUq #define APPEND_SIZE 10S7xqt M%|}
H+qn(B,o5J!Z&f
struct SNode{
FbJ~5E     float data; /*存放操作数或者计算结果*/
h'R6[$^0@^     char ch; /*存放运算符*/
+dX V$_%n)j };eM'yA` C2h.~
)b`$Y3W^OL
struct Stack{
+mtl&Uy2NPY     SNode *top;
bJ nv7xb8DN     SNode *base;:n/Xn9}5F w,AJV
    int size;-m {"~o,O
}; \ r~{S1}1jaU:Qc

qBr7EKR u)Ni /*栈操作函数*/P#E1a@8D:]g.@na
int InitStack(Stack &S); /*创建栈*/[D9|3LnlVfiw
int DestroyStack(Stack &S); /*销毁栈*/
``)mkv9~ int ClearStack(Stack &S); /*清空栈*/
Nr"NB ru int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/%gk6l)s8`^
int Push(Stack &S,SNode e); /*将结点e压入栈*/
s&G:{%WdU int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ eOdw _5l

|WIm s/a2kxW /*表达式计算器相关函数*/p"] `-J nif
char get_precede(char s,char c); /*判断运算符s和c的优先级*/L'FR4iL`1wf
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
c+]U r}:u3K float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/TgZm L5p
float compute(); /*表达式结算器主函数*/,[ iQAQ9CL+L
char *killzero(float result); /*去掉结果后面的0*/ 4b&B4I vE_"Ce%m&B
0RLz8kIZ+kZ3X G'N
int InitStack(Stack &S)9e]W V,y
{(_r ~{w;U O
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));H,F q@/F#O
    if(S.base==NULL)
ok5E0Do{t     {"k:v-CE^&j9H
        printf("动态分配内存失败!");Qx nBFQD6j
        return -1;4c$B/COw"_&^
    }
j8t4{w5GQ     S.top=S.base; f:~/Z0L7ma2F
    S.size=STACK_SIZE;
D2D]#@3VB,x*}2ngdQ&x     return 0;
7a y7Uxmf*sh4[ }
x.M/qhC7GE H
-f1QUjLu{h:] int DestroyStack(Stack &S)
Ps"QY G!Pw"@ {"GfBn_&E
    free(S.base);
9q$\aZ+FfB:`     return 0;M Br/h9I m"o
}
XpcsB,n e |
(be#WFb8L pl int ClearStack(Stack &S):V5~bK'j]A t
{mcU_x'h5u!mKbp,S3{
    S.top=S.base;
A7K U&~4M_-Bf     return 0;Y!bm5z4SO o
}
;U&oJC,{ ?r,De i:D-hF QpXv
int GetTop(Stack S,SNode &e)A-J9E;^I)loygS
{ j*s+l-OG1A+i
    if(S.top==S.base)9n3p,v6EJT
    { P nC\+q2ju;^ K
        printf("栈以为空!");
l5c0n:J"A3{~         return -1;
4Bk L,W-a1UGm3V0G     }2gL6i7kf.X
    e=*(S.top-1);%]?8Mr;H*BW
    return 0;
'u8N7gLZD }1nGx+c0h l
n0e!F x/g L6x
int Push(Stack &S,SNode e)
9IQP~W&X&d {:k.m0nEOy7]TI
    if(S.top-S.base>=S.size)
k'V lG!hXk     {9x`.nX"h*mz
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));v:gN*[e"[
        if(S.base==NULL)`4_D9M;VA
        {
!Q ^ |j-[GlY3q/w             printf("动态分配内存失败!");
b3q^i&W+b/v`             return -1;
5O*JTo,DR.@&Y         } QE wZS~3o
        S.top=S.base+S.size;b7JV_|-Kq
        S.size+=APPEND_SIZE;nS*Pw&J#xgo!F,nU
    }
zx el:pP$b5XH.h     *S.top=e;
1ADt5dU }u     S.top++;
h3zTY:RE     return 0;%`tJ|:[#~5?
}
r q$O;i)s G'W;n z;H\gK#G0w
int Pop(Stack &S,SNode &e)R NB],a}0gPH
{;M:P"h5j|/cXH
    if(S.top==S.base)|#Q K F7Vy
    { A]#B#o8a
        printf("栈为空!");
E,Dp:aKE6x         return -1;
6Vg(B$d1f~c     }W,vU0ZFkscE
    e=*(S.top-1);
Z"Kb-V9U(@.mA`     S.top--;4d0N4M@E2O
    return 0;
i*wcj4W C S2F }(T7p d,n-E!\
i ksY'SAt_
char get_precede(char s,char c) aa"X,rI*I6[
{
w)c r PUrB     switch(s)
4_^'{MH~     {
2@:J6Bky         case '+':                 
4j#}5{ a-@P.lV:~         case '-':)^|*m{7D~`.A
             if(c=='+'||c=='-')7?`y UI3Q
                 return '>';
,K$g t3DZ*AB              else if(c=='*'||c=='/')
LL:}-nZt+N1qLe                  return '<';C P?*X*Y%H%z
             else if(c=='(')
a TLBL(J)I                  return '<';a6FO J+U2x+T
             else if(c==')')X%Knn}{J K
                 return '>';
Xe!J)B-[1i              else ]`y*lU_OR
                 return '>';
/K)`4]uVfP!` ?(N'g         case '*':-\vpo&L
        case '/':%P\"L0N(U
             if(c=='+'||c=='-')
Pqxs6S                  return '>';&uTL(Xjc+^
             else if(c=='*'||c=='/')Z5Lm _)eQ
                 return '>';LH+M$k!Q;V v^
             else if(c=='(') J'FN:BE k{"F
                 return '<';
0c:RW:R*| Ot(g#k              else if(c==')')
D9Gx$`'|1g!~                  return '>';
!]q}8R*J%u}Z.~&c              else.W W,lY:d&Td%@E9s
                 return '>';Lu G+n+Mv
        case '(':*{"X8z'B TF!H
             if(c=='+'||c=='-')BI ^\'M9o
                 return '<';
f Z.`2x0`p3`              else if(c=='*'||c=='/')CS9s]A2\j6|"e
                 return '<';
^[X0I%C qohr*Pu              else if(c=='(')
1N ]+\OWS*Y                  return '<';
s$`Eh @+J+x(nt D              else if(c==')')4I Pc#Ku$j
                 return '=';
^)^w&hedZ              else
I!@(S tl4Gsb                  return 'E';
)t \ceT/S h         case ')':
T~hPe#| jD/l#m              if(c=='+'||c=='-')
0U a-j;~&E                  return '>';
y6A-C*BA.fs:P T              else if(c=='*'||c=='/')
K|~?&F:v|)N                  return '>';
q*O~"y(z B4iTY n              else if(c=='(')
O2w0N6`Cl/WEj                  return 'E';
_N%M+Y;q4n B [W)[6?              else if(c==')')
hA$ilo#p'V$W __                  return '>';
M\K#bkS              elseUKy n6Xvz`
                 return '>';
TA2x)op ID\         case '#':
\3M!Da*wtT$_              if(c=='+'||c=='-')8{G;i&nm"yt
                 return '<';
.]]p1F2~#{e0B)M?              else if(c=='*'||c=='/')
%m;nnl _}                  return '<';*qX7a$dc,F,cQP
             else if(c=='(')4L+A6X#sil3|
                 return '<';
#r0Y;F,]FsL              else if(c==')')
Z!r/Q K%O HbG*d                  return 'E';
6}g!iAh@;G;K              else
)\i6?no;ENf(C@                  return '=';
hI]|/a?         default:N+mVV_Q
             break;4`T v!Oqd
    }L(G?e.d }
    return 0;   
7f%ywn cr8n }%Rp}N H2Tw`
5G2t0nEq ~
int isOpr(char c)k5_ k1c!H4P
{;^\8Hi3H U9N
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
&U4Lo*Mr?         return 0;
q%vA$eW!cte     else
~%Mq[5K)V"N         return 1;uCFds
}
U9o7YSr(Q2`3q0QH
a9G[3G.ya dn!] float operate(float x, char opr, float y)
!Ii9\,F3ew { {kn+x+b,g,Jo G
    float result;
zz)n,^9~F"c     switch (opr)
WJO czHnl;Z     {
{om&K?1c9X O*p         case '+':
$C:B.?$w$F k `jl D              result = x + y;
v `{9Ced7`,y b              break;:B#~['I0|.a5ht
        case '-':
i`vc7M,M,TH              result = x - y;
o rw+lf@2le^              break;
v k"S[/mp7k)JG         case '*': 0icH#K8U+L
             result = x * y;W+rj `!D
             break;$B+w1| T\K y
        case '/': 7yHA0__;f n
             if (y == 0)-_%^-x/} ?
             {#Jp^yf1Az"S
                printf("Divided by zero!\n");wj\)tD
                return 0;
w,a'w H0om              }s&XkB-ikq'[aD
             else
E e:fg6tl0E0E/v              {MNK3~F
                 result = x / y;3xMu C w1z G
                 break;
ft+pf$G z8y              }yq`fv1Be J8_
       default: 1@1O0D/^f4W N
             printf("Bad Input.\n"); 2q@#v!W/zX/RT5b']
             return 0;dMY%E.C4qz
    };JvI1S z4V `)^3~P8C
    return result;
)XE%i-D E }   
,LwXk X#n
zCO}~ni float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
n)}B*VZ$Xq {
-Xu_sz`$r     Stack optr,opnd;
V w Gh ^     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
R2T-ca4r&P     char c;M0F'zp"veUpS-I
    char buf[16];
&E5P jzRW)@!l     int i=0;1\M Z$[2O
   
+_Pr!w[W*mu1r     InitStack(optr); /*用于寄存运算符*/
?_x2E@!\'a     InitStack(opnd); /*用于寄存操作数和计算结果*/
0[&J)y'r)C)a     memset(buf,0,sizeof(buf));
3@;N:L2w4S-Kf~     N6z Mr+sH{jP
    printf("Enter your expression:");
mpF.g `.hN L G9j.j         O:u,Ihl
    opr_in.ch='#';4c.e `,U-]-c4zr/EE
    Push(optr,opr_in); /*'#'入栈*/
5b/[2G|/f     GetTop(optr,opr_top);;Kxx vr&Jh6m.F6nO
    c=getchar();
v:qR!]'i     while(c!='='||opr_top.ch!='#')*c?1G N{c@.U Y._g
    {|1P'}8Z cY2i
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
FT&@ C)NW#?K j         {'R5XuS*GE u [5Mv
            buf[i]=c;
'uX_3u}"A+{!Ov(Tg _             i++;
)W y$@3Vl`             c=getchar();
$i|*`G,ID1U5C         }G T0e I@"B i'^8`
        else /*是运算符*/9{"u.T:\ne
        {ha/F:{8cO8F
            buf[i]='\0';
B*\1xS+S0YBz             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
;g1Mn/Gk-L$] p             {+j I em-n+R om
                 opn_in.data=(float)atof(buf);
8A Z_1o(t                  Push(opnd,opn_in);5y/JMY9u;`4p,T${[i
                 printf("opnd入栈:[%f]\n",opn_in.data);q(th L#G2P `]%A_
                 i=0;s2\}L&upO;] M Bm
                 memset(buf,0,sizeof(buf));
fIQ5}'b%Q9z4H'~4o             }
n'@{!h%h q4t             opr_in.ch=c;
gC#O2y(_:buM             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/t[J MdD
            {l4df{4w~ w-k8P7@
                case '<': /*优先级小于栈顶结点,则运算符入栈*/4[s5f*[(HG?Kv
                     Push(optr,opr_in);
s'jG JeXmb1i                      printf("optr入栈:[%c]\n",opr_in.ch);:hWO0d"t&{ b
                     c=getchar();
a]$M8|0BU                      break;%W(Ld t W
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
]`+kA^*p q0C                      Pop(optr,e);!^'`k;Dk,v%P k
                     printf("optr出栈:去掉括号\n");P3RQ%CL)U!`P
                     c=getchar();o#H8]R/gf2O
                     break;
/K6o%gR!_ip[                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/$Ax5q`4E?6{Y
                     Pop(optr,opr_t);G_ N8p |QDP
                     printf("optr出栈:[%c]\n",opr_t.ch);
:slZ"[B3YM4t ZT9]#@                      if(Pop(opnd,b)<0)`!`:aL4U7R(W
                     {
o*m~'lr q                          printf("Bad Input!\n");
)?P?*D(iE/I_%UI                          fflush(stdin);
)B H2d~!}/j T                          return -1;3U.~/Ki[
                     }H^:w5Zu4L8P"P }
                     printf("opnd出栈:[%f]\n",b.data);
;Z:e [#?QJ$kK;Cy3~J                      if(Pop(opnd,a)<0)2jB"b\-RG~:`
                     { S,p"Z-i5m#V6M?
                         printf("Bad Input!\n");(]:S#[l(F(|
                         fflush(stdin);
&l5|Qht&k'cM                          return -1;
z-s7{i `#Zo                      }
)Zv_2ncy                      printf("opnd出栈:[%f]\n",a.data);
}i7z@-hNsr k.w                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ AFOu`1V#m f
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
6_!K c%]RnbU                      printf("结果入栈:[%f]\n",opn_tmp.data);A b c@!Mw
                     break;8]V!\ j0G-Uh#A
            }%|aq}(re
        }'P/aJI}5N
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                D-i _8Pb6_
    }
Enb7hgt     GetTop(opnd,opn_tmp);w {lG1@#M&]#go
    DestroyStack(optr);
)?k7}7k|qc*o     DestroyStack(opnd);sk!cCgI
    return opn_tmp.data;UqFN.~'Q
}#E3g6~| f-E3k ]
*D)z.eyt9W;Qu9^t
char *killzero(char *res,float result)
k;|!d8@+z,h {
r4d*d5YH+wg)SDA     int i;
ZRo_*]2B8^:fE3@2v cp/U;d:{3T\iH1]
    sprintf(res,"%f",result);
8Z,bgXO]0U2x     i=(int)strlen(res)-1;o Nq6D)z L
    while(i&&res[i]=='0')'T\ b Q?sn
    {%AXO-N(hvc X)@
        res[i]='\0';
NX\~gXSI9tUI         i--; ~*ufJ.L| jGL3RS
    }k8D4g)q5`!~&Ewi
    if(res[i]=='.')hh(~1y;g7mg0}
        res[i]='\0';h0k"l nw
    return res;
.C%F J'pa L(t }
wd)L7_B0Up-l
#j@~(U"u;~ int main()
+{Q1uo'_| { J~]"x/OD;tH7O?
    char ch;
MS*l)r0m)knY     char res[64];;J k-Y ak
    float result;@ p6?(`9l1m.~"e
    while(1)
~c/C"h']l'd6P     {N:l6v4~[3f9y }{#M5M
        result=compute();
iyE? f,j9X9?         printf("\nThe result is:%s\n",killzero(res,result)); P}@ x G-d7f]7W
        printf("Do you want to continue(y/n)?:") ;'v ti,y!wg^4SUj
        ch=getch(); T mO oP!C
        putchar(ch);
U#{'Wa;f wA         if(ch=='n'||ch=='N'),P!d;{)\W-X
            break;6dK_6Zz ^._
        else
avo xt%^t-f#~g             system("cls");
? R!T0|R?c     }
{*l](bO4x-m4?H     return 0;vu(e(^-x(RAfn
}[/i][/i][/i][/i][/i][/i] v E-]S1jj"`

ti:cE5ii [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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