捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.I6b.VL|8r\Y
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=:ko+X+]1uT
/**************表达式计算器************/
$SFIp@5\m5A #include <stdio.h>
,qL8| kU-v9p.Q\^ #include <stdlib.h>)b1mR$n;|{I
#include <string.h>
2_S`B#_h2o/o #include <conio.h> G cET h B U`D.j o
#include <malloc.h>
8yw:I&?J ?
$D4vg,?)a #define STACK_SIZE 100
U0]Zj5`&D_)E #define APPEND_SIZE 10?A!rq%M&^3_zA0xT"@

^r-\%J uDuF G struct SNode{
%qW^&ab+{"lS*D.b     float data; /*存放操作数或者计算结果*/1~m-?!C n Wf
    char ch; /*存放运算符*/
O?W+T @?V'lIn };g R3^*Iov4z'}t
{A[;Lc+m+[j2]j
struct Stack{M)|Z_#x
    SNode *top;+_ L0N y U7e.vE [ t
    SNode *base;z5C0xv? ~VG
    int size; [1It cF
}; w:Y`R5PI)EP

tJw1L? /*栈操作函数*/"H w/Rq.Z {8qyb
int InitStack(Stack &S); /*创建栈*/!v xGX1@d3s
int DestroyStack(Stack &S); /*销毁栈*/*J0oM6Ac%a,Z
int ClearStack(Stack &S); /*清空栈*/
DO9{M!Ls'F int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
/Y;V:r{ yT!F:jQ int Push(Stack &S,SNode e); /*将结点e压入栈*/
n/{ vSn)R j1aO-n int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/E1b s8U$X:H&D`*O,k

Sw9Q_6h O8P-q /*表达式计算器相关函数*/
dH!k0e E*} q char get_precede(char s,char c); /*判断运算符s和c的优先级*/
&t]+MFPb } ^/~0k int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
+[n U3N)}:U.i5a,x_ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
Y#F9Bh-E5kZM ? float compute(); /*表达式结算器主函数*/Y+K+w]vV)m
char *killzero(float result); /*去掉结果后面的0*/
#m4k j3eW6?*O@9tC5Jg
@ V)]U'p$p-J-^L5P int InitStack(Stack &S)
2d6D;?;O(A%|+x {
-s+@ a!^h*]uf     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));9MV-]&`S)|.P
    if(S.base==NULL)%e:h1`9]c
    {T Y q+Fkg U
        printf("动态分配内存失败!");5B[ h,]'N6HB
        return -1;/U~0@f.E E5x
    }
(|Uz$sI/\#j;S     S.top=S.base;,Y!@,S#z@A
    S.size=STACK_SIZE;
3X J!x%k+v     return 0;
zc$V*gs:`$p9N }+W`~ rYX"T+],X
-Mgb8Z3VC
int DestroyStack(Stack &S)
9e emNV:G z] [!aS {M,G d-qpO"O9@
    free(S.base);.~DnX1TC0\ ?
    return 0;N2X`q f;I
}5MD8D7f5f-dx

f7\1cX2] ph_ int ClearStack(Stack &S)
l%B'NFE {oxnKx GZ
    S.top=S.base;^w"V;kp3?7Et^
    return 0;W-B;\.u)H%R
}
4px(uk;k#RTE ;n0k&n ce-y I
int GetTop(Stack S,SNode &e) ?^4P\3^
{
!JI4r gJ;P[P:rZ wL     if(S.top==S.base)
"I }:P\ OYV3h     {
1Zg U(t8} _         printf("栈以为空!");
aJUC~!K         return -1;I"r M:qV6u(\9j a}u
    }&@2i]vE)^HKz
    e=*(S.top-1);
/ar|&]@1H `z     return 0; kUMG:[
}
%|dS8NS [!SaM.P
My.^3x/J OHs int Push(Stack &S,SNode e)
.Gs)pQ~%`x {-s6Q!_&R1f
    if(S.top-S.base>=S.size)OA2q{v(_6U1nc
    {+eivC-S3sA
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
QY?,` v2e;?         if(S.base==NULL)
6{%C'wJ_4L!m         {PE-|([r N8u'B
            printf("动态分配内存失败!");
)Uj t3At0WD^po             return -1;
~l1eVE/z         }
#n%XZz+jZ         S.top=S.base+S.size;8ij^s ^"@7X!HwY
        S.size+=APPEND_SIZE;
wvO Q)qLn?L     }O-Tdn"cW;RC(nH j*d
    *S.top=e;
H.E$U)I)v g,HJ? \\     S.top++; ['fSp!hPe2n
    return 0;
,h8J:sl)DA%h }
iW%xz x ;\:?OHQ6`o~%h!I
int Pop(Stack &S,SNode &e) G~$Ws\Phc
{
&Vs*P-I:yk3_4U^/K{`     if(S.top==S.base)da)s;pX b(d
    {
"g1c3W _"T@)}NR         printf("栈为空!");
9WN,d#rK si         return -1;,^2hDKt5h h/gL0f)z|
    }-n {W C&`.e&][/_
    e=*(S.top-1);8~u}rm Z&r1q
    S.top--;BeW8k7T Z
    return 0;0E9K/Ra%[4z$w]/tbZ
}
2?e th&q U[
#b,GwUS"`j char get_precede(char s,char c)
;@[3uR]yPT {$y+l d~F4@4_ m*~
    switch(s)
+b i6Y7bp)DR     {{s Xr4r#uJ
        case '+':                 
T2Q,P ^T7@.b         case '-':
as*D!PU*] Zh0d              if(c=='+'||c=='-')bm ]v\'?A
                 return '>';l\E8dY}~
             else if(c=='*'||c=='/')
}n$cf#Zrv4k!{oFs                  return '<';
y;s9h dZR              else if(c=='(')
5UN"g)sJL%mb2n8C0n                  return '<';
f4F'BaE/sd }T              else if(c==')')x^G*n I lt n,Y
                 return '>';1dYd8L{e$L5b
             else
CF2]Nk`f,]                  return '>';
N e-C3a Wtv w2p         case '*':
.ZO8| as9Pl;Gw+t         case '/':
c d6B0N4T~3v D!K/p              if(c=='+'||c=='-')
QlC+\/{                  return '>';e2z H)[c1V+d N
             else if(c=='*'||c=='/')9J'k/p*`9oA&L!n0C@
                 return '>';
7X+P3q{](r#P{u;~F              else if(c=='(')D/e?@;?{Y
                 return '<';
(Tbd8sv+fg              else if(c==')')
r)Om9Z9zCe c ]9U:Y-N                  return '>';
$I(]{/Y5Wh.w5C              elsew7]/_\8Z;K^6N v
                 return '>';
&r4b}q(Lm%PR         case '(':
(_.lVj}S'fGZu(m              if(c=='+'||c=='-')
n@Ic1Y                  return '<';{7z8}0]B
             else if(c=='*'||c=='/')kx ey}*b
                 return '<'; fY E}8K}M
             else if(c=='(')
m2^0^"jCMV3f4D                  return '<';
7]J(A.``:qR^              else if(c==')')
C%__$V:ar'?P                  return '=';
;`DP%B@"QD!k8H              else
:g{W^9j                  return 'E';2L u ^(Y0vy
        case ')':@E ~4C&T \G@
             if(c=='+'||c=='-')
)eS/D/cl.f:lf4LG                  return '>';6mj UIY0P
             else if(c=='*'||c=='/')
4r g M E-C&]                  return '>';|_"M1SH fT
             else if(c=='(')g/z![ Ofn7L|"?
                 return 'E';
k \ c o'a6@.Xx              else if(c==')')
$})l^8nE8CK                  return '>';
QA)J:v KL              else4P ye5|;k h&d
                 return '>';
YM tW,p9n         case '#':
W qs9pTx}/YK              if(c=='+'||c=='-')Vj#r%}#Eh n
                 return '<';&y y~A9~YU;Y
             else if(c=='*'||c=='/')BQ/WUEA2Ar
                 return '<';
,~2Jt BU:Rp              else if(c=='(')
Z{N9CI,hJ                  return '<';+Uqdd-_1lk{#vex.t
             else if(c==')')
T\ P hLSD                  return 'E';
G y)jr-Dbm:D-u              elseOUb8BQO1Qz
                 return '=';l#gs/X5nrL
        default:zA-E&ez
             break;UAvx J
    }P+U*u)FI,w
    return 0;   
cx5P3Cg I }
"n2z'qg.K"KCSC'o'b
Dd5Bn;XeW int isOpr(char c);b3E*S1`z7E9q.L
{7CU y NzJVX
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')ul'@9t8C+Yd"[
        return 0; u Y5w:dY
    else
&{t9e)v#a E2QB W"X6^         return 1;Qi'clix1Mq
} s9n-b1[:L

i(`)ey'I8V:Qf float operate(float x, char opr, float y)B%A8e[Yw
{aBO1e)y
    float result;-c1W(ME V#RMT
    switch (opr)|3YY7ZF'\#D+N
    {*tO^qE
        case '+': _)Uz"y Mk4r&M
             result = x + y; z"tmak7a1| L
             break;
rj.?po K         case '-': #Yd:i4k LJ.`)C
             result = x - y;9X0F8q i%h gG2d{
             break;
9ia r'q.n"Q$[         case '*': rMtd fzb W`
             result = x * y;,FR%kI!T
             break;
-bi2c_1d/I,DE-x9\E0|         case '/': PNW:s6\O_~5a D P
             if (y == 0)}4N4D2@#cD,C:aV
             {
Vd_2?I4Ip|Zl                 printf("Divided by zero!\n");qi;~;H jAw-t:S
                return 0;
jz3a"u-]I              }
2~&WGr*p&O.[}/wy              else
(c4g+`/m"N              {
6h/E%eh'Y){d                  result = x / y;
B x*H'SG@6D                  break; k:^nEd&U
             }mL0xv+ux0q
       default:
`B Mf0S{ bTt?+d              printf("Bad Input.\n");
"enb G;w0P6w8Kd_!@0o              return 0;S{6vhhAf
    }@Qf#S$}.C3[|-p
    return result;nB^P]
}   
W*C?%H8^8kh
m3SL"d~h]/j float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Sp;[N2J+x {gU5S_"R'T8l1V
    Stack optr,opnd;&Dm|5i3j X"V
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
$A:?SnA q     char c;
P8V#L U4T8k/}     char buf[16];
| ZX {$z5VD%V$qs%X     int i=0;
(f%_'axJ    
5|7g0J9s*F@$H;t@)p$\     InitStack(optr); /*用于寄存运算符*/
I&~#H8E.J2e)[e     InitStack(opnd); /*用于寄存操作数和计算结果*/
|I(c-D3TLy Y/b Pp     memset(buf,0,sizeof(buf));
)A'~yV(l1F%BG.|z    
)?6?FgS2NCP     printf("Enter your expression:");t!F@KB
        
)l,?K~ } W3P     opr_in.ch='#';*G*|3S7rT
    Push(optr,opr_in); /*'#'入栈*/5`#k#I.w E*Gf oA2L%~N
    GetTop(optr,opr_top);
lw6Sr]6NN9@     c=getchar();c!A P;N$`r_0G
    while(c!='='||opr_top.ch!='#')Z [ j`:g
    {;Y'U L4q'x(A&X
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ M?i&WK
        {/t8FGH;q
            buf[i]=c;$A:j3? Mh n}Z0C
            i++;
(HYJ$CI.}fN4}             c=getchar();
-Huf%o+Bu!w)nB         }C5q-s&cY g
        else /*是运算符*/W O`0chvU
        {Rm@(b}
            buf[i]='\0';
{*YAm#B:n3YTk             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
W&R6{#O*RA:q             {
,y6uigx                  opn_in.data=(float)atof(buf);9VPRa wWia
                 Push(opnd,opn_in);
.C:e,z5q A\4|:_                  printf("opnd入栈:[%f]\n",opn_in.data);%\Ul4\ e+~.uok
                 i=0; p c-g6C)w,?
                 memset(buf,0,sizeof(buf));
Ft+JxO E             }0~2uz^+nD"v#h
            opr_in.ch=c;u#@Y%Y3c#u~3g
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/K+cB&i1D0_:Q'@[l
            {!I^|xa Y'l B
                case '<': /*优先级小于栈顶结点,则运算符入栈*/'r,amg6E M0p
                     Push(optr,opr_in);(y8j1os]sEQ
                     printf("optr入栈:[%c]\n",opr_in.ch);
h^9C p'p?U o                      c=getchar();
@2aT-aOY B$}                      break;'q|L0|"j5OA
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
aD,m YRdK3j%j+oi                      Pop(optr,e);
8mvhj{"n%Z c{/}A                      printf("optr出栈:去掉括号\n");
-K!Pll?z)bKA1UP                      c=getchar();
Ms!aCc3?L                      break;
dMT ?3KE N } } BM]                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*//X7V(xn:U5P1b.S.X,tJ
                     Pop(optr,opr_t);o p:pcG
                     printf("optr出栈:[%c]\n",opr_t.ch);
-T;X;e0@;h{YL                      if(Pop(opnd,b)<0) Z/s-i9a)j
                     {:b w+b5C%v XH
                         printf("Bad Input!\n");-r(w"n7Q:t6rp
                         fflush(stdin);
|9K7|^_                          return -1;T-IYM.A'k)c
                     }l$lfm/[qv[+vF
                     printf("opnd出栈:[%f]\n",b.data);
0VX,B+a6|e                      if(Pop(opnd,a)<0)H^(U(j*u mj
                     {'e8npi/f4ra$X s!i
                         printf("Bad Input!\n");
/}D7X2r"z pB y                          fflush(stdin);6cayMx;E^.R!H
                         return -1;
0M a2}!C.f"i{                      }6b]2v(KK
                     printf("opnd出栈:[%f]\n",a.data);+{/P#| L8Vq;L ~H
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/#i*XPR$NZ%Tdi
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/1]lK)D ~6e G t+?Z
                     printf("结果入栈:[%f]\n",opn_tmp.data);
vh"q0ie o%_z                      break;
:H&\0a X1`             }
r4Zog7{!q }/lh\         } `8z$_ }S#kn
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
1H+h?f:Ev%cR };w0GN     }Pf?c5y_.xo3K8~p\
    GetTop(opnd,opn_tmp);6tW6j0[E-IjC
    DestroyStack(optr);
$y#m f t3O [f-Y     DestroyStack(opnd);pw sG"wsh D
    return opn_tmp.data;O9fC@7i*`)G
}&h8|!` A nE \&`3SO.Z

v*n oJ+P#x.v char *killzero(char *res,float result)
C;S:|_R"n)} {
%j3a p#\;os     int i;
l1Zh5t!L2ak?Q}
.D.ZvM_c5O     sprintf(res,"%f",result);*V;v PK1a]0QY6fS
    i=(int)strlen(res)-1;)h5cKS7} do
    while(i&&res[i]=='0')\$q#~?[#FW7D
    {M]gL,}{
        res[i]='\0';
8I1Cz!x Q hn         i--;0t2p dd1R v
    }
X%l*G6Bs[     if(res[i]=='.') ND|f]
        res[i]='\0';
:L0i$~c(M$u     return res;CE@F B3MzP
}
'l LxW$_.o|5p s~oC+H y9px2q t ~
int main()
np l)O?Zt { Ib0t`)s.\
    char ch;$^Z'F1_8I
    char res[64];tO-q-jy'| @h
    float result;
2iUi q)`t     while(1) g#mDtnH
    {3y'@i;^Y]:KE
        result=compute();
h ?sg8`         printf("\nThe result is:%s\n",killzero(res,result));
J)QlxAY o\*`         printf("Do you want to continue(y/n)?:") ;`{x0iEB
        ch=getch();
]S#c#t:B0r1]         putchar(ch);
wvJ:x4s ]h         if(ch=='n'||ch=='N')Y gG9f(Nl+?+[0f
            break;
z_!P;RRc         else"FX2R a"u @M2s
            system("cls");Q9V#s#X6m
    }
0e)z0WDT     return 0;
rWO3N.?a!` }[/i][/i][/i][/i][/i][/i]
)V a Ot+T0t'F@H6E.J g,H'Wg.W:Y1i
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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