捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
G{ [0KqX+[R 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=:im} J!l!p
/**************表达式计算器************/c YY^%[:P)VL/tr
#include <stdio.h>
0s!v#c iN6n#U #include <stdlib.h>^!T[`'U @3[O9H$k
#include <string.h>4y5i`_*`s*k:]G
#include <conio.h>
4j:Z.f,r%z(fF\ #include <malloc.h>
5\)H ~+\v6EV Q7z,@ etv
#define STACK_SIZE 100
}dvR;S&Nt7|TsB #define APPEND_SIZE 108Si0h(|)e@:L9@)b"I~
]w;K9p@wh
struct SNode{
3Ld#g;Xg%Cl+Z4U     float data; /*存放操作数或者计算结果*/
kK4eu O9p0\ y+O     char ch; /*存放运算符*/
'\)g"g.O9W };
0T2f,_5@`
/^D%ZA9j x BKu struct Stack{|:vf$e!p6E#p+Sy
    SNode *top;
S_qG&Y:P*Dm     SNode *base;_7aw-U(z-N
    int size;
D ?/s2qA/GL uy#] };
5Z^%^0GH-\X/}3K *M ]f F ^8b
/*栈操作函数*/l6N;G$J8v\(vM
int InitStack(Stack &S); /*创建栈*/ d&s6P%F`O qjf-?B `
int DestroyStack(Stack &S); /*销毁栈*/
.L+A*egtPX,L$_d/s int ClearStack(Stack &S); /*清空栈*/ ?eX4D}]3QC
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ I(N r7DD
int Push(Stack &S,SNode e); /*将结点e压入栈*/NjQU5b OVx@
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
8K6T0lr#]d\
M1Z })o(fb oH:_ /*表达式计算器相关函数*/!BMJb+TN$}y!}
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
sk/k:K-AC~2F int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/#~:R!['B2Bi iQ Pa2^
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/]7b5^5^ EA#?
float compute(); /*表达式结算器主函数*/
+T$c~/o6i c.k char *killzero(float result); /*去掉结果后面的0*/
],b@1S9frqGG
Eyg!Y7DKy9G int InitStack(Stack &S)
u:uq)]\:p%O {1k9@6t_T*?5ZljVx
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));#s \Y.B"Q({0U
    if(S.base==NULL)
{D5G@5W1z xL     {,G InDo:g
        printf("动态分配内存失败!");
e4j9iYU         return -1;
f eGY'W     }
$D{t8xp/ylG     S.top=S.base;\)Dr,i-@ { b
    S.size=STACK_SIZE;&qY@tT\f*u A
    return 0;uMRCY$g8K
}F(?#C+LYm/Q,A ~
'RC3kAE_?JX
int DestroyStack(Stack &S)
s| U+a6^l-f {
#Z_OVa x&GW     free(S.base);zM mr!~$G%y
    return 0;
2cA2aa%F%H }3H N\2UClAy

a&a4|9T1eI { int ClearStack(Stack &S)*Vk-J;p3FC[GL
{
f|z{#~ h*p     S.top=S.base;
k U p r;[ z@     return 0;*N(_!V/d/z-{ mC-c0DP&b
}
0j E#q_4|Oq 's&C|!@(v#|&L&g*@9^'l
int GetTop(Stack S,SNode &e)
wv1^'dX {
0e:UX,d~(t;W9d8z     if(S.top==S.base)
3R&y ^#Gy     {)c*V,nDoO;V e'y
        printf("栈以为空!");[@5N:Z*`N8A#K,K+i
        return -1;C'F-K:\(i!y
    }Kz/_]lYT
    e=*(S.top-1); EnQi'B
    return 0;
~&U!w wdd}lm _ }
L6X$wu5s'P])`,q %L]6y l Q W~
int Push(Stack &S,SNode e)&? \+?7`O]^ j&|7W\m
{4S~k \q0y1O N
    if(S.top-S.base>=S.size)
1QC|6YbK'w}     {
3[f cqD N_E         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
gN"FXjS         if(S.base==NULL)QD_;P)UH6G
        {"SnY)|F+np E
            printf("动态分配内存失败!");[Q/O"S}7Zs B6iBM
            return -1;8bH1UP}&Y }FEO
        })oVTa}H m%i#Hh
        S.top=S.base+S.size;
'n4?$jVh ?Z-F         S.size+=APPEND_SIZE;}1XZt}d/P
    }XpG6TO1Bn&Qj5}
    *S.top=e;6TpM q] d4KjSS
    S.top++;
g7E1Bm6z W W     return 0;
&hx6E P0{ cr }
0Ki2niX}"j8qF *@r9vq5?Q.\u
int Pop(Stack &S,SNode &e)
3A+B9N Z)M5OW(m {
5j)D7f)@uPE-X'l/L!e.b     if(S.top==S.base)
6P&tvm-R(J     {
~'nvRDp}         printf("栈为空!");
n|U.}saX3a,x2F         return -1;
P SC kK x     }
:MA`}_     e=*(S.top-1); mHe0V:v }bi1h#i Z
    S.top--;b(`|^?\'A
    return 0;
mU5h'S?fc!Y.R }Q1D S Eu0[-I v)L;[ EQ

QU.a$t6X d(yS char get_precede(char s,char c)|4m~k A0H5F
{
uL7sNDJA^i     switch(s)${Ary ^ [ lb+R
    {:DH7Q m8\+k
        case '+':                 
Z`,[Dg o         case '-':n G*x-Hzr
             if(c=='+'||c=='-') ^scB |
                 return '>';
%wk3pHb;~/x.d              else if(c=='*'||c=='/')"Y6n6kr&EF
                 return '<';%g+[j ?&^ O%L:?
             else if(c=='(')E;s0@_`(`1b%sD
                 return '<';
&~})pD*PS              else if(c==')')R+Fk u[+qXE
                 return '>';
_ nM'? b6o/SxL3KR              else wG4IQZ j
                 return '>';%J#Yzc!]A_f
        case '*':
8Hjr#H&_!ns ]         case '/':
uqd q,kmp5{              if(c=='+'||c=='-')
'aA"ca%|                  return '>';
0\ c|:GBS-[/b)E4@W Gc              else if(c=='*'||c=='/')
;xBb:}R,}*F|W                  return '>';
$nS7n p*f:w)i3i              else if(c=='(')
8m m&f\y(k2qNL                  return '<';\^{I;nmC}:AJ
             else if(c==')')p1v\!S'~3}F
                 return '>';
$PWK'mQ-st              else
Bg1n)Qe                  return '>';
![:e?;fj:J)]         case '(':
e ySt'Vu+S#m'g6K d              if(c=='+'||c=='-')
OZ/_go/I                  return '<';
BS'X1e/r \              else if(c=='*'||c=='/')*H^~qRPK n'z1E
                 return '<';
(Y I DG5{9s-T)l Y              else if(c=='(')/m xidVZ
                 return '<';
u)Y.^a:uQp!]              else if(c==')')!yD | WU?7kIs(v/c
                 return '=';
$b7} X-CnY              else6E.Tr/lr
                 return 'E';8m;IP$n-jjZQ
        case ')':
e2x3s%w y C              if(c=='+'||c=='-')#W ~tkKs0V
                 return '>';f'S)L&@7f jx
             else if(c=='*'||c=='/')"w|+F*}7YIx
                 return '>';
8t"oclD0Wh              else if(c=='(')|P N/s9F+NtH%x
                 return 'E';"b2G@AD.x.L:\
             else if(c==')')
-Iqhw.o`                  return '>'; }JNXV3B:P
             else6\3GN e`)Q?
                 return '>';
eG0T'pnm         case '#': q E;kqr+QhA p7C
             if(c=='+'||c=='-')
M @8duXo\%X3G                  return '<';
-h(Z#l^l0z3~U              else if(c=='*'||c=='/')`Pl(gT0g
                 return '<';
l$Rg v _H              else if(c=='(')
R+e/{XZ;V`b PF                  return '<';)Z^/S|.KZz3e|2b
             else if(c==')')xn[:]q'[!xq
                 return 'E';
T{9]sU              else
`^l Zo8H\                  return '=';x Seyfb&` x.e
        default:6A+I Od1Yv3Sx
             break;Nm iQw6@B
    }b"U9l{WSY
    return 0;    Ro g`I` E0j4_3yT
}
-CX M0~#h6f id+Uz/a3o+e(u
int isOpr(char c)]$aIPip
{
4iwtD2V3[     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')_x;G7uVBm v|\*i
        return 0;
#a$?3s5r,]It7]~'I     else
*Ei.Ym%F%C#Gr!Ti         return 1;
!`#^)]o"}$U-v }-CkT"z*d| cf5L0Ie
gr:h r-iDz.L9Aw
float operate(float x, char opr, float y)Q'V#[;N#r]#u
{4\I n$SYF/i }7MW
    float result;
,o|*C/XA     switch (opr)#t&Y cQ?[XxN[
    {
8mL!eB8r8v+I         case '+': CJ V GH W)Y7a
             result = x + y;+B t-Ta-o4G V!X
             break;
7z)hZY9Wp;It7P         case '-': Uw:j G ].d,s
             result = x - y; E&e6LZ+@
             break;
y x&MI4Nb;GXf         case '*': 2wg"uJ(b Nx I5KF
             result = x * y;O9^zN!J:I
             break;
:Rg4JO1nN$\P2e         case '/': nK B7lH ZV,M.I fE
             if (y == 0)
,b @ F7QH8Q{2r&Q              {
~ ] ^Qp m                 printf("Divided by zero!\n");
7|p4~gH,?V"H                 return 0;
3bGDGSzk              }
wx|]`j              else
6DC g p [o$]              {
-Q7N)f;i7q6bj                  result = x / y;Yz!ZK M#Q
                 break;
j6xwR;u              }\%^-[o0u&Qg7T b
       default: !?;t [%U E*Uv*W
             printf("Bad Input.\n");
-S&@uN6vgI!b              return 0;{"a4S&Z'\ i\'|E
    }
!?.Sm5XU     return result;1X,`%o_9x[ y%_$G-M
}   
;\+W(z#EXx[
V#y1_(FI9j _ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/6}X C1|pnt,v
{
6w+J,YvTF     Stack optr,opnd;
@&Md R'u l(a     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
JHm+X-u)B*T;p     char c;
*L qGW2E9S     char buf[16];
[(T}-w'f4[4H     int i=0;
_ ET4c.m     ;TW-c1\7@c7}
    InitStack(optr); /*用于寄存运算符*/6T3hw.[2\X4I"@BG%?
    InitStack(opnd); /*用于寄存操作数和计算结果*/
P;o.wI-@-T     memset(buf,0,sizeof(buf));0FcF;mL4A6~
    sO1X&o C#d"RuIeS
    printf("Enter your expression:");s3M*J!w@ o z!V Sl f
        T2E5D:pGCxt
    opr_in.ch='#';-Kl [*tCvX
    Push(optr,opr_in); /*'#'入栈*/
hVKm_(n2_     GetTop(optr,opr_top);U.[@8K Cn-HE
    c=getchar();
~CL?t     while(c!='='||opr_top.ch!='#')
9a*B!a1gfs.X2F$P     {
.Z_T:w`l;^         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/{-@D!\ ot0ho-miz*E
        {x0KY \;B#s
            buf[i]=c;Fz|Sx v!P-C
            i++;
-r s$T%M7y!v\1p             c=getchar();
|8fh*SxEsDi3{?         }]3KyB _j(@w
        else /*是运算符*/:} T1\|X$[P0[ \K%w|
        { Y G]$x,[&t.r7z
            buf[i]='\0';Q J2lV#?C j
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1j:e,N$\"R8H
            {5o&Uq'E:Sqt2G
                 opn_in.data=(float)atof(buf);[gd(@~H
                 Push(opnd,opn_in);
E`} Rv2k$yw [T8xu                  printf("opnd入栈:[%f]\n",opn_in.data);
b6q_5E2J2d                  i=0;f:R!y&}#P6S O&o
                 memset(buf,0,sizeof(buf));
Su cy$S `,?&|7Fu;t             }
['k(v7q)oi2mB}             opr_in.ch=c;
%L(T8K\8Z6E(SX4E4| C             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
^+w4yc:uU             {
V/a{xfWHB}q                 case '<': /*优先级小于栈顶结点,则运算符入栈*/ {;LJ:I1M!u
                     Push(optr,opr_in);
[ y3gT;`l"g                      printf("optr入栈:[%c]\n",opr_in.ch);
!}s zn@5\                      c=getchar();
l k-tb+x(]6L E-v                      break;V7_ jo3h7}L
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/\.x$XS?&` v
                     Pop(optr,e);%g$y3THqz'p
                     printf("optr出栈:去掉括号\n");
8I"Xb*C6|                      c=getchar();
s1XLxQT!h C|                      break;\9r+u_XeE
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/R Ucz(Y%r
                     Pop(optr,opr_t);!r:xZ$`,k0C] b
                     printf("optr出栈:[%c]\n",opr_t.ch);7I9e~BK'f"c-e
                     if(Pop(opnd,b)<0)
2f'HN7m)m/[G                      {
!vZOIU8WF                          printf("Bad Input!\n");
^ L!X Nk] B                          fflush(stdin);4G;g} e+l `?(@1?+o
                         return -1;
;l7|hf`)OQ"Y                      }
*Q NfU&D                      printf("opnd出栈:[%f]\n",b.data);bP;TBW)I*p
                     if(Pop(opnd,a)<0)i4Pt9?8}%zs
                     {`'Y3X3zq9UDy
                         printf("Bad Input!\n");
P&F:^)N kzw.}@                          fflush(stdin);
k j |X&i7V!NtS                          return -1;
2DAhk^3R                      }
Cn#dtj([q.w4X){                      printf("opnd出栈:[%f]\n",a.data);0E0ch SI
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/*v$pi4hPvf
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
&G D`IR[Ll2Ch                      printf("结果入栈:[%f]\n",opn_tmp.data);ok"ynzfe[ F
                     break;2mV`/`5O8OVw7q
            }.]s$UkD$PR}/m
        }x^"Vb!@ y_ lgL
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
0BI,J.z {NZ     }
w0HW@\ h     GetTop(opnd,opn_tmp);
ac4dyS}mjGF     DestroyStack(optr);*b$Z,hr:u A5P
    DestroyStack(opnd);
sq9|K E ~'Z J.f9vw     return opn_tmp.data;
jJ)`3J LC N@)mI }
wQ*qtb
ppw&}m char *killzero(char *res,float result)zCZo+w!D0FOQ ?
{ yNx0h E T:e'@
    int i;d1X)SN!vc{!~.i

*H?/AV @?K6O     sprintf(res,"%f",result);]|`Z0P
    i=(int)strlen(res)-1;-~$KB(^s+k}
    while(i&&res[i]=='0')
xSemS/F3r     {Z.j3M/w(BO ^
        res[i]='\0';9o4Z;n-V I+}D
        i--;
GP+O5T${??xi     }
Eh8t#UBq3kj     if(res[i]=='.')
AD)w-k |Qg         res[i]='\0';(n-n(| e2~ H q3B
    return res;GF8F-qw2Q
}5fB W-Dr

1E{:I`*E%a int main()
uA4ka+gc@6Y|H {%f+X,_/P0@ `7g?
    char ch;
)U KULGAD C o     char res[64];ae2^dl&g
    float result;e*w6Q.oSv tC/p
    while(1)+v5Q\ xHpUz1m
    {
3g7^]qG'~!L!Hp         result=compute();
,cm\5Fg'y;s+`.v         printf("\nThe result is:%s\n",killzero(res,result));u k"o9D-b7x
        printf("Do you want to continue(y/n)?:") ;@Ov0`{+r,u'RQ
        ch=getch();Q BVL4`)v
        putchar(ch); V%n+hC!^8^7SC)Zh j+N
        if(ch=='n'||ch=='N')
i4|6A IL             break;S9o!{!o?X#o&`
        else
A c?{6ZG1`'e;iA             system("cls");}a Yv#E1SM'|h4[
    }a@2s.Q%yae!Ga
    return 0;
vC0w-d!S1V }[/i][/i][/i][/i][/i][/i]
:T Q3Y/Zb!ui:x
I \ L5lE!xy:Ep [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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