捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
x0Qkd-WG/e*z&\ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= \U8eu$|G If
/**************表达式计算器************/
\,z.Cx8d DWC #include <stdio.h>
2UXq}#Y\;L)p #include <stdlib.h>
:jW/^1L.K #include <string.h>
T_] PD5] #include <conio.h>
(vW2Kdk #include <malloc.h>H3Kjb h'pdZ

b+dO_+~6o #define STACK_SIZE 100)c*y3o#p9NXN!q
#define APPEND_SIZE 100OAL$}9S'N(kr"Z
D3Cu-f5Pt3b2o2e2[
struct SNode{
IQ$N#y-XY     float data; /*存放操作数或者计算结果*/SV A~#Vh)E
    char ch; /*存放运算符*/.WXT$@4@p1C
};T1E+_M7ZyZ^!W

sR^j^Z!] struct Stack{
^A1n6Z)Y'o     SNode *top;O6yq)EI:S
    SNode *base;8x2l{"qr!c/w_
    int size;U+k(K%n9k:@
};
H+J1w"AG$u5p8cT
pW'R c8NjBe /*栈操作函数*/
@zi tJA*Z int InitStack(Stack &S); /*创建栈*/F(C1_Sb;K
int DestroyStack(Stack &S); /*销毁栈*/
]mNQ7j int ClearStack(Stack &S); /*清空栈*/hLO R8]K Y}
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/m\ R.SF4VcA @
int Push(Stack &S,SNode e); /*将结点e压入栈*/
j.s*b4j5R_V int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/M5Y-}zyr4nh

#owOs7FO o /*表达式计算器相关函数*/
f,M@7h+K8G char get_precede(char s,char c); /*判断运算符s和c的优先级*/2yxNAG%T}
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
a3jD7w"|oU float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
+aIZZ'a N%TgX~ float compute(); /*表达式结算器主函数*/C.@iz,ySp2e
char *killzero(float result); /*去掉结果后面的0*/
+D:`Hx(npX9H3W]*}
8V/eTs0Vb6f int InitStack(Stack &S)
/n UkL%Jh { Q {o|N6B6A
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
1?p,K2m:nJ R|x     if(S.base==NULL)
_:m&V?8R+M*Qj     {
]q)Kz%BAe%i[         printf("动态分配内存失败!");
Xv KLX Iv)bj         return -1;
q \8^'jd5Dz(Sr2wY     }
d3dH2O5S$s5Ym     S.top=S.base;~/Bqc*zSB
    S.size=STACK_SIZE;
$^~g"Fn     return 0;mVs$jI0g%S
}$G4s^QdsF

h po8|y] int DestroyStack(Stack &S)
S^Zue {BYMp#`2B
    free(S.base);.u ^,w3\)S
    return 0;
Sl#W H"EP }
`P9y hEF#Xx
I5vE `rV int ClearStack(Stack &S)
x]p3nO ` {
;|a[W#Qk@'F     S.top=S.base;
m\PZgWFi     return 0;EM,nEGpa*no
}
+D*d-{)zwYc9KY8m6KU
z_P jV1B{9] int GetTop(Stack S,SNode &e)/{ j e!x n#\Y+Q0W"Mx
{+]R&SFd\5{8b+X VE
    if(S.top==S.base),l?H-x*I u!^O
    { xOO#E+M%@&W
        printf("栈以为空!"); {%y'?-Q+uh:[!R
        return -1;3h3~A Q*BFi
    }X#p[.q6q&o
    e=*(S.top-1);
(P?W5@U~ zI~e     return 0;`no f-jeA
}
k9YsZ ew5G/tU#`F
]gb?]U int Push(Stack &S,SNode e)
%fyluyOgq7Z {
:Tp#N}%|     if(S.top-S.base>=S.size)
B}8dkdY"Qs     {
6D^ K$j u         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
jDfcZlw:W         if(S.base==NULL)1[%| O5_/\Q4?+|
        {h/[\#zf X`
            printf("动态分配内存失败!");
"lO'D4N^4J RW!v             return -1;
c v fL;B         }tM8aL },v9CT)_t
        S.top=S.base+S.size;
/A UET:?jId         S.size+=APPEND_SIZE;
QVO+y0@(CX!a     }
m w:[:With6Y#r     *S.top=e;
*IXLu3?]*Wz     S.top++;O|$fq$yRa#J
    return 0; q2Ba8Ah-i0D@j
}
`G3rTW$WM
9e%v&Vxf"H.s(jbf int Pop(Stack &S,SNode &e)
iwaFZ;Ec {]Y%u+d_bID{
    if(S.top==S.base)5N7\(Yd%d
    {sxvL'iL [x!{3Hq
        printf("栈为空!");
NZ2Y1b6S4k(g/s5^-b         return -1;)G1@:RL0z
    }R"y3p FE%y-E:q
    e=*(S.top-1); UL:b4Sda[
    S.top--;
+N4S(H$Bv5TK}^     return 0;
Ix.^Q };j/]G)U!A }.NcFMq^}'Ph?

(L6mE1H7g}6kQ char get_precede(char s,char c)5mFnV`/_g Z Uk
{[2["?OS
    switch(s)
u,Z}%{ T1f hd     {
y.Q `o Lg+L1[2X         case '+':                 
)}z-BEAh_         case '-':7b\D%Og1|'{$FG
             if(c=='+'||c=='-')e4}%d.`_ScK#C
                 return '>';
])yb SMs              else if(c=='*'||c=='/')0P QB q hQ b M^
                 return '<';BB*I)f'il+~(F,E
             else if(c=='(')
f3Lw"daf O                  return '<';
9j:z ]el5S7p&`%}2d:Bz J              else if(c==')') Qz9~0rS'l(`8XA
                 return '>';
yn4`u ~(ehi              else 4rnLWCj'vC
                 return '>';
VH.t8H^yp.O {:Na         case '*':Z]6Z(?sa
        case '/':$~5{*Y-{ W!nA A#Y K
             if(c=='+'||c=='-')"@NVlr"{,d8tZ
                 return '>';-EP+Ck1}%]
             else if(c=='*'||c=='/')%Kd:R~t/S
                 return '>';
5kLr*r6a              else if(c=='(')7lb9q `FH&D
                 return '<';
yS0W'l{3ql | Wyn              else if(c==')') PfuX,th9a2]8_
                 return '>';(e,@I#^9f.Diq
             elseg'^ _"R-k,Y&`%`
                 return '>'; Nc&l[}y|9YA,l
        case '(':
w3U]F5^P              if(c=='+'||c=='-')*Zzu o*]s0`m_
                 return '<';
B3c8T3}@*lhdw              else if(c=='*'||c=='/')
tod2szy+{+XX6_                  return '<';
0k7Nqq0_8A6M6r:e              else if(c=='(')eut/v"]~ g7hg4ly
                 return '<';qb#oh?a|8WxL
             else if(c==')')
\d`;gG?%ZK                  return '=';
vH+A'o*B7OB              else\.{(q^DK
                 return 'E';
-D(J e9k eRT DdD         case ')':?M&ZJ8t
             if(c=='+'||c=='-') QC^g{3I
                 return '>';5ysJn?R{9g
             else if(c=='*'||c=='/') Hf\TD0^ k~X
                 return '>';
O"i[7j"Q u              else if(c=='(')/k"E&`5sP}F
                 return 'E';
!UaGbs~"^7k5yr,O              else if(c==')')!h2l FRlFD@
                 return '>';1X:imK^uJ
             elseq8Stw k?
                 return '>';
%J5p%WL?;I n7z         case '#':'f8~,|%hss
             if(c=='+'||c=='-')
5c7F*T1im3HZ-g"~@                  return '<';KQZD(SR.e;mW
             else if(c=='*'||c=='/')'f ^|BU%go+}
                 return '<';8H.C0u Wi%s!a*J?:dg-y
             else if(c=='(')
{O/]cWvM!x%e                  return '<';o(e(K:~4o!o G]
             else if(c==')')3Y PobWQ'z
                 return 'E';
Z L0^}.L_              else
:}:Q@P(q B/kY                  return '=';)r8^jk8H
        default:
0{7`:hCx~              break; Ha It)~"?&U
    }?@?mjv
    return 0;    3xs1Br0h7HW/eBV
}U0X)P Z{4a

#vMu'K%QB-rNe int isOpr(char c)"pS9eWk)[B
{4\g'J8qRL
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
q)TZ-I^4C         return 0;
h#]n O\L [     else
TD'i*y_4u,_         return 1;
"M q$\^cs`] }bK5HPFH\ }
:~.E!D#_~ m
float operate(float x, char opr, float y)
1Y(A+l4^U_Q[K {
&K OkRK%y`9IP     float result;
)RlR EEZ     switch (opr)-\%|z Y4`T uk.|
    {
3j`#EkUh$^`B         case '+':
o)QLNq:D              result = x + y;,bW&un[7]$^I
             break;7gU|$Va3yMF
        case '-':
)L1_9_]y5KH&b3W              result = x - y;~+wI1PQH3E
             break;
!Q4\S|O^%e/x         case '*': 4G or)\I-l
             result = x * y;XD4[5y"OC;Y
             break;
K%^|4@ r0dq         case '/': FCi8BcE#K%a8z
             if (y == 0)
:vW5|:~Y              {
l3Z1_V_6Z,[1{                 printf("Divided by zero!\n");
x$y-qd(bT                 return 0;
9@P.njFm {3^5|              }
)CR ve*]-Mi              else
5n R'GR4k8b%h5D;HA              {5rb1n-Go$R%S
                 result = x / y;'TAj'CM?"HY
                 break;he})Ta L-c
             }2hTpQn%?~-U)t
       default:
k([\u!v+SzS.t(@              printf("Bad Input.\n"); m5J0_ I6V3m4n i
             return 0;GW0^/H0|#wR
    }B:\d+{.m2TJ
    return result;0N-^Xs6TN
}    X;`d@UQ1g:TRM
j%U2d7q-a]
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
XXv3^CT {
"A-M LH$uWRf&^)RG     Stack optr,opnd;;Evz [7G3@~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
3|+M d0h['ue     char c;PdB Z4[)R'o
    char buf[16];
L0A#}*w%p/vM1g ?     int i=0;
Z5x Q%K^&D J     g/_,K7A+tH2y
    InitStack(optr); /*用于寄存运算符*/9fq9_jhGA
    InitStack(opnd); /*用于寄存操作数和计算结果*/4O)v.{ultT
    memset(buf,0,sizeof(buf));#LUXW L0]"~2`#kT
   
@7r8r:kS ]$@.}*`     printf("Enter your expression:");AD3Jk#\3hj[
        S(Q.Jq,S;?X
    opr_in.ch='#';
,q$ETE ?@;D     Push(optr,opr_in); /*'#'入栈*/
,x},X$j7v:KC;M.W8a     GetTop(optr,opr_top);
*^3m3[RC_%qg     c=getchar();/Qcz3G7`IsF?
    while(c!='='||opr_top.ch!='#')fX.Fn f0q1j!g P
    {MIp]6L
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
5tn gc.yP4b         {
T/{P-j%J@ O `2{|8MJ             buf[i]=c;
k2[#~7i*HD%rQ`             i++;
A:z2m~'M#S @a'Y             c=getchar();
*O0J{3SX(v2m'j![@         }
X3u&a{A9j] q%g OX         else /*是运算符*/D4W9N C*w ]CP
        { R0s"lF2j)d
            buf[i]='\0';
4~7|b2Z}|fx5_             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*//r&f|4PzE
            {
j9|7J(`;u3b&k                  opn_in.data=(float)atof(buf);
h H-Y#}0whs                  Push(opnd,opn_in);{*Y5kzrwN
                 printf("opnd入栈:[%f]\n",opn_in.data);rS;[#@o,K
                 i=0;
"M*s V7Wy#j` r'K j                  memset(buf,0,sizeof(buf));
1m@.to'R?h_"xa"hr:m             }$v(W(]a*U(RJ
            opr_in.ch=c;
d Q m'qyW6xlQ             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/D6iw/] ~;_k
            {
u'c-W f'K:Ilfd                 case '<': /*优先级小于栈顶结点,则运算符入栈*/n0\9Gu&d i3R
                     Push(optr,opr_in);
^'lo a4m6XP6tkd                      printf("optr入栈:[%c]\n",opr_in.ch);-I5wEa"Z.d.{!lG
                     c=getchar();
&IS9j-|;sw-c#?^J^                      break;]_9Pe2?-U;a"f
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
S2h8cIyDh/Kb/t9P0p4V                      Pop(optr,e);
Ok#?9l$r'T}'TM                      printf("optr出栈:去掉括号\n");s"\m*EtH X9v [ys
                     c=getchar();1r9m Uh7dY-v
                     break;Nv\U2l?U5vWz
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
[ s*p(W;aUL$NK                      Pop(optr,opr_t);#t)bmP;`6A?
                     printf("optr出栈:[%c]\n",opr_t.ch);
k(o\5P ]"rK![                      if(Pop(opnd,b)<0)
-BZ6e?Ge8HA                      {
;NY9[&llh;?                          printf("Bad Input!\n");
;tO@rsJ0\                          fflush(stdin);;l4v:e"p#[E {0['f_ w
                         return -1;-@M`&~Y7N*r ds
                     }
d%H b` a D                      printf("opnd出栈:[%f]\n",b.data);Rf$}zB;`G$DKP
                     if(Pop(opnd,a)<0)
|V+hB ~:z                      {
myT z+s                          printf("Bad Input!\n");7K R9T-~!YZ5N{5]rN
                         fflush(stdin);
&hhLZ p                          return -1; R(xL-P]0r}!^(a!P
                     }W/VPo[
                     printf("opnd出栈:[%f]\n",a.data);
p0R:|.MEyn                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
bCW-CI7G                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/f `1XC"uX
                     printf("结果入栈:[%f]\n",opn_tmp.data);
%bQ+S.Xc5d5r3i a$k$n%M:}_                      break;iB#f4M,IW
            }
n3Y3Gn-MOQ         }
(F-y E [;e0^         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                ;LV/Q4uA%L(Mj Z
    }a,[.^P/aQ:P/_
    GetTop(opnd,opn_tmp);%r-tz,uY
    DestroyStack(optr);
0` Tk(]ZhKE     DestroyStack(opnd);(G:sNV#xmL-J
    return opn_tmp.data;
7J9r]q5FJ#{ x }
gX5u3Pq!m+Z#dw-}
n+CeC3y Q char *killzero(char *res,float result)W [{\,~vT+K(@
{
*Ap+mN0qNHw     int i;
)_]F|'Z5b(L
kx;ozCz7u5cH     sprintf(res,"%f",result);*q_6F}!F(GI6s"L
    i=(int)strlen(res)-1;)es*Kt7r:rgj
    while(i&&res[i]=='0')
oX&O8hw.Z+q _7Gyk     {
]5g,F,G"Y&~         res[i]='\0';
/j)h"b%S!ki5Q         i--;
o a$K.C5Z%m%k     }YZ/BX i2n3Cj'{
    if(res[i]=='.')
]9~*LFu!ah         res[i]='\0';
YUVi/S|;]R     return res;*NX0wq:ZL6h3lI Z
}
/IO`*Y7^L$O7n/R 'I||9u-`A \z
int main()|0N6p:@.h$Fs
{
:G+n"NfkL     char ch;
.T;v K"Eu     char res[64];3Gm{|(i5^ @%xy
    float result;q2Ftc9d4o{-o"F
    while(1);f9t"y S9j}*?9T#d;a#pP%\
    {
(h\4_5NN8|         result=compute();
NU;h'?Y$]-U h         printf("\nThe result is:%s\n",killzero(res,result));
&S kk%IW6m&SP*c         printf("Do you want to continue(y/n)?:") ;
%u }2N'HO#l}         ch=getch();
twyz5lWqV1l6v p         putchar(ch);
mV`Su a3W9C:^#M         if(ch=='n'||ch=='N')1qt,i AX3HEoZ9k(x
            break;'[ua `t@ g;w'jO
        elseV K k(`d.y"rb r(_'^
            system("cls");:D:B C(P&a
    }
2@[&V t ^/L/cf     return 0;
B2Nrs#W4SR"V$I3R;Y }[/i][/i][/i][/i][/i][/i]
2?;Pc8} ][gJ%qT
vu ?PS-K6_8{P [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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