捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
-A4wk+Fj U u%Z 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
l-f3r p!cO%C%Q4m /**************表达式计算器************/mt K6qv(kya
#include <stdio.h>
o2g&W6m|%f0v{ #include <stdlib.h>+p8Y4|4} H5v3h_5f
#include <string.h>
` g0|u@^ #include <conio.h>
~O J ID h7hdC{-w #include <malloc.h>
#a;U.d R*B'`|f
1o^0PIy9Zb #define STACK_SIZE 100
8og!b;vVl)d #define APPEND_SIZE 10 i!d3`6Oc:bg@ ?Mw
0]H$mS"V;Yc
struct SNode{2R nR7y5t{ H&lj
    float data; /*存放操作数或者计算结果*/
,Nz0B EQf"H ]{!j     char ch; /*存放运算符*/
0d"OAN3V^ };ye [W B.a4{-q$x4s(r

AmB*`Phx struct Stack{ rA~k?6Q
    SNode *top;
:` F(}]`PQM8C     SNode *base;"o%J%g V e+s%N.g
    int size;
+g'm3X%M@:{zRbK x };2`*[ [k'R9{e@ x$wz
ew4W(l4~4EeA
/*栈操作函数*/
tdm.n0{J3`p2N int InitStack(Stack &S); /*创建栈*/}"|+h/[^c;S#G}x5u
int DestroyStack(Stack &S); /*销毁栈*/
-m0a)n a$kJb'P int ClearStack(Stack &S); /*清空栈*/8X,R1k+S @-x|1r
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
Kv;rmZMs\H9l&V int Push(Stack &S,SNode e); /*将结点e压入栈*/_ e/{ T wS&OrU v Qo
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/_ {G,D)Fhy`
a.K|!ur
/*表达式计算器相关函数*/7dD"oi'W
char get_precede(char s,char c); /*判断运算符s和c的优先级*/5IY5L0I,BY'U
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
p7|$iz"Y L G#G float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/\qnc(K3t&FY"}
float compute(); /*表达式结算器主函数*/$D0QB"`3B7R'I
char *killzero(float result); /*去掉结果后面的0*/ .E^H/W dv6`

!@8`&P%w{)R E`LR int InitStack(Stack &S)
c0}v$vI {
[2Y/g!Or&C&d     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
5x7}#A-S7[%o(j     if(S.base==NULL)
%WH+g6h/|8ha+I     {|I;Jg E} D/U%S&sc J W
        printf("动态分配内存失败!");,a0nU.h[7A5j"R
        return -1;
6}d&lD)m;L zIKQ     }
z5{s]j_     S.top=S.base;
+Ei!|7^*D:P     S.size=STACK_SIZE;
)GUfS9l$^5_     return 0;ygi Z0_%W
}h2vw1RhI$P

U[9`;s"k int DestroyStack(Stack &S)
{;P-{$v{o {
Pf6UZ R;[     free(S.base);KZ(?6}*\ bX vUS
    return 0;
;}D*r b$_7dY"m }
w)o4F:N)jOo
2]7qP jm jZ int ClearStack(Stack &S)
c;r h+DK {
O1r6jS(m$p)K6p G     S.top=S.base;XiE2Ckq#Z6hH
    return 0; g/N1~0K6AED*Z
}%f \l2G"s(J

)OFG2bZ)O!Qg int GetTop(Stack S,SNode &e)
:Aa)OP9@ o3A8Gr {i b(Io!T}7o
    if(S.top==S.base)}"L|9M(q%B'^
    {
e4Pi%f,pYFK         printf("栈以为空!");3ai w?4A"?
        return -1;-?^txZ,@{[
    }
oI/b4Qf     e=*(S.top-1);&U{*|1CbR0R$u
    return 0;
Q7~'ES0V8| k }
Y$jl6hg^[t
~}xOVxQ3D int Push(Stack &S,SNode e)
S M x/rsZm {!aBPU h p@5g qa(w
    if(S.top-S.base>=S.size):K@9j0k(t
    {
6H WgKo0f |         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
~w?xtB/e"D|         if(S.base==NULL) y"@2G&M Iq-?$L
        {VJw9L'] N@
            printf("动态分配内存失败!"); m&PwAvKR
            return -1;6m@,h"A ^Yi1_?2M
        }
s8O z*rq         S.top=S.base+S.size;t#AWjM*v-j
        S.size+=APPEND_SIZE;
m9Jal6Y1Y ^     }
*`X%eR1[     *S.top=e;}/Zf-M4Ss$@
    S.top++;:ZQPt?:T
    return 0;
|\%J&Y(p:zt }
a2eXE{K
W'q W M1x1] S3yf#N int Pop(Stack &S,SNode &e)C8h7EwK
{
JD_-[v9E     if(S.top==S.base)0BpP"Oj/l*CmL0O
    {
y*UApM0Bn         printf("栈为空!");
mO'GhYK4q$m@         return -1; H-O9tR|6GYi
    }
DF%}r@6i}l     e=*(S.top-1);
f2v BmV I;U|     S.top--;
_ v| f P&R     return 0;1Q+T8Y$BN\
}
U`;[,^C7hd1U6SET;P:\
F/vi9@ pC&{_ char get_precede(char s,char c)
wO1tc@8H6g'\&~ {4lNE4{v
    switch(s)
JU7ozF     {d4ir}(B
        case '+':                  R{$}s#F^A
        case '-':
*~A0LH9L4lnK]K              if(c=='+'||c=='-')4]#y*S5K A!o4T2}8Y
                 return '>';CS;U%UU
             else if(c=='*'||c=='/') E TG-_kI
                 return '<';
(t1vc4_#Td-O              else if(c=='(')Q8U@5};qW@N
                 return '<';
W1l'I [)OHE!j              else if(c==')')
ZU4Lv/L$c                  return '>';"K D:L c4Psj _
             else
,vAY4Pe?ND                  return '>';
9V8a g3jzj/j         case '*': hp"HSyv
        case '/':
6r/L+HOJA?T'P:A              if(c=='+'||c=='-')
%? @quLtju                  return '>';
UQ:i6Q*J6a4Z              else if(c=='*'||c=='/')6a.xr$ei3H"Z w,SbK
                 return '>';
?~X"Hi o!{              else if(c=='(')u2C:{)TgP/c
                 return '<';O SR/w~m.C
             else if(c==')')8F1O6i ? yKl)C!c!y
                 return '>';
,Q2_/Wwu E:sy ^+e              else0z8ZG-LW]^$w
                 return '>';
!Rvk9b:jLU5D         case '(':L kfmB
             if(c=='+'||c=='-') QQ{(q:D t&@
                 return '<';
qX9K)n^|O.K              else if(c=='*'||c=='/')
ZeIf1J                  return '<';({'jq}9GMD}`u
             else if(c=='(') Zf9~Z\9aC~
                 return '<';
:l/L"FAI g"cyf              else if(c==')')f K]B/Z9k
                 return '=';Z*iM(hp(I8|)y
             else
Xu(t+R"g                  return 'E';IV#] Z_z+\
        case ')':
{ cU3xwfs(\{"_              if(c=='+'||c=='-')
O4m wJ0MS7~                  return '>';1N.lNw:jB(Z
             else if(c=='*'||c=='/')7HGp1p0b%n Mi
                 return '>';
i6aIk0w9d              else if(c=='(')5v)LH9FF&jZ8h
                 return 'E';y$LK%`3]{
             else if(c==')')\^)Y!R7h!|)Z
                 return '>';
wh?G3_)Q#?#h{              else
)m}:ZLqw,V A                  return '>';8Cm R K!]}5I
        case '#':,g7}"`i }kP
             if(c=='+'||c=='-'):S*O|]c
                 return '<';?.x zuBB
             else if(c=='*'||c=='/')$B;TZ.r\$Jmr8{+\$BA
                 return '<';
%M8KVv bB              else if(c=='(')
*zPH KG/Z#H j:SB i                  return '<';
h8Y*^c7j7P?-N              else if(c==')')
f(u6X(p._y}];M                  return 'E';
6N DR{~T\              else
{"[#B'Xal                  return '=';V2Z(H+O"v~(n
        default:Y H*AYy E$LH
             break;!H;e9Tr"n_\ C
    }
nM1J6eI&twZ     return 0;    $Xa SL/[C P
}
SB]-I.f A,Vy"C d {*f{U9x*G.f
int isOpr(char c)
,yD9~e-R~)|3F {
P.VHSt2Gw     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='):hgx/FPvx
        return 0;Yl2ou1X8B
    else [s9v~0Kb8y
        return 1;
F2]0u*HQ2f8R } r(jv;Zn8E0md)\aH
#NX+ppbt7E?:g
float operate(float x, char opr, float y)
eN3{3A%G)J9Yu {#D+nRq'g] eJ
    float result;:`"xR0tL+A9H u Als
    switch (opr)
t^ o[}1OG.w     {;L-KVFHjS v9tUf
        case '+':
Uo)H qUm              result = x + y;J@-m*S3l[4|8k/F8W
             break;
TaA%g*bZ         case '-':
m~7AuS[ @x              result = x - y;8F*H\ Y f|
             break;
4^P9bG4}&V-o%O         case '*': H%`5YP{4AR+a
             result = x * y;
k7~a%wvcoS)A5c              break;xl_f2|8gc
        case '/': izR1T3j [T
             if (y == 0)9GfTw2SZ-gaQ8C2k
             {.N"b-L%NF iu
                printf("Divided by zero!\n");
S;ES9ObN8Kd                 return 0;
-d{2u v'BT*z-a EAT              }
4qa?w"n/ZC @wQ              else ],wVx0n
             { h,A] P[ F:z&L
                 result = x / y; Meg#m{9hY9y
                 break;
io?+QV | J8|              }{#o+J:@%oT
       default:
6yA\j3_              printf("Bad Input.\n"); 4b5kc }y,w$}@x
             return 0;9{fln hOE J4v2C:rd
    }
t+kJS$d7x*Y     return result;
e3GZ'O*o-QI2~#h+z }   
/ZPRR i~j ,b+{;AI0S1J eB
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
~2n?9h*@ l {.EW6Q v0w_Y
    Stack optr,opnd;K X \s7~
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;m KH|*kY
    char c;
lX*~Y+{ _H?     char buf[16];
P!Y!?/Q$r4] Q:B1rOI3k     int i=0;0y)|i3_5j.la+a
   
9`2Tj$o8Ct0]E     InitStack(optr); /*用于寄存运算符*/
| ic9I3m2J*[     InitStack(opnd); /*用于寄存操作数和计算结果*/{Z D:o^m
    memset(buf,0,sizeof(buf));
S`&?/pTf     )U A2?+Ob R0NN
    printf("Enter your expression:");
Z `%u }6]:n8b6DAK         
@kTf;@     opr_in.ch='#';]c2Ic/V$j
    Push(optr,opr_in); /*'#'入栈*/1K\mVk&Y |
    GetTop(optr,opr_top);:n6[%s9\n ?.FdB
    c=getchar();(^ a*Bj"GAy UEJ B
    while(c!='='||opr_top.ch!='#')
)HhrF+hN     {
p9P I(FV)r#V(d         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
.} x+M+P.r~7W         {&v8F%EO K?
            buf[i]=c;%OB~3\4p*I(t*X1N
            i++;
y a2GAV _:W y1};q             c=getchar();Lm;bmp&qT
        }
@2w%Vc/vS7q?Ds8b(R         else /*是运算符*/R,P\R;zd;m
        {C0Vq+[jI
            buf[i]='\0';f:J'z Vx&Z
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/A7~*y"mO)T"B
            {
S5J}|Tw                  opn_in.data=(float)atof(buf);
e0U q(qT [ N                  Push(opnd,opn_in);
:u`t9T6D*x b                  printf("opnd入栈:[%f]\n",opn_in.data);/UKa9TK~1c$iJ
                 i=0;
[edGIq                  memset(buf,0,sizeof(buf));g^.])n6f[g`G
            }
E c-pG$u E^oVo9pB e             opr_in.ch=c;
cM"MGEC:M!X             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
]/p3F#tr4o             {
n#T h` ?KHlj                 case '<': /*优先级小于栈顶结点,则运算符入栈*/9i5x m*w0w@9GLr
                     Push(optr,opr_in);
m`'l5g.[C                      printf("optr入栈:[%c]\n",opr_in.ch);
.o0nt} RCz:e u                      c=getchar();
E*p;[iy:WZ] v1_                      break;
;c#uNZQN                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
S.@w1o'd#e8A)y                      Pop(optr,e);8un4p o Ec'?"b
                     printf("optr出栈:去掉括号\n");Y {q r @
                     c=getchar(); CS;z9w&N5c
                     break;
~],G%]y&]                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
QBM*p$m6Q$^`                      Pop(optr,opr_t);d&}3Rl Y9gE/P5C
                     printf("optr出栈:[%c]\n",opr_t.ch);
7QK c4Kg                      if(Pop(opnd,b)<0))Iqk6M$sHz
                     {r%CM x$M:I _&u2w7p2J
                         printf("Bad Input!\n");-l6h@ }OD7~Vu7pc
                         fflush(stdin);*Re i1U&iI\
                         return -1;.jTY(L Tk5Y[
                     }
|3Jc gE,Xz8b#G v3r                      printf("opnd出栈:[%f]\n",b.data);
?)n0_7nAZ                      if(Pop(opnd,a)<0)
!~S\&JPAPUO                      {
5{z8]9mz1UE                          printf("Bad Input!\n");
]1u'LPp!T                          fflush(stdin);
jp#F/~yZ9@u                          return -1;
:p Ch6J+`                      }+t2I,iU8d@go
                     printf("opnd出栈:[%f]\n",a.data);
,J`MY"u                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
L+Ti R^om3T7B                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
W%["Kq*T#~h(jA t                      printf("结果入栈:[%f]\n",opn_tmp.data);
X%_]*?D!tni                      break;]FOKfe
            }B~2DY)kZ:jr
        }U"qj%fP5\ i
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
e7A}viLY#lC     }
S ?Y(Coq6E     GetTop(opnd,opn_tmp);9|m,}2M.V
    DestroyStack(optr);
"GW_*R&D:g3n r)z ~[B     DestroyStack(opnd);
"Ea&h%h7|$W-B     return opn_tmp.data; h)}D*tQN
}
3K PE`Jqt~;b
!C ~Q%` b-H char *killzero(char *res,float result)
NhDp_ g}yV7` {
A8^cK\!j MXRL     int i;
PZ+k \3R/R5JAUM 4Ix#eP-T1O `t
    sprintf(res,"%f",result);
fd){j9s `     i=(int)strlen(res)-1;
4VC;E:T:`w0_8h     while(i&&res[i]=='0') s4l[8F(e'j
    {8hm$\b;HzN
        res[i]='\0';
3bZ6z(P5ND-^         i--;
9R3q D/T7Lw$xC;Y     }@Y-W@i!vQ3Br
    if(res[i]=='.')
[:ZK"z;hksA!A         res[i]='\0';
E^ \"| X$mJ     return res;T+s/gaW
}
4H2u6Q-E Zs
F4Q8V b2} @\*I*[ int main()
%DG?ei] {#Tz Ly+L)[ r
    char ch;
v'm@p3Ke-vl`QCs     char res[64];
7BU]$E R\     float result;
J]fF$O9j(?#u@%\X     while(1)
3t$Z3PJqe#b_)J+T%o     {
&q)Aq/U/To:mB\1z         result=compute();
~UC9F$`         printf("\nThe result is:%s\n",killzero(res,result));m5O(_9{ D3P4x
        printf("Do you want to continue(y/n)?:") ;h#A ]Y$gt t@
        ch=getch();
"W`t5E&Zy+_DL$Wp         putchar(ch);
5\.{U1Z"pk         if(ch=='n'||ch=='N')(nx4n#?g
            break;3Iaq9A+M/rF
        else
Mb l%}$@             system("cls");
n:@M{lpg     }b2_,YsHt*FM%_
    return 0;Qg!@5s:rWT9K`3V
}[/i][/i][/i][/i][/i][/i]#a&Q*@?reEpO*A

*y&L^/g(yq3V`C+i/a [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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