捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
A`F#xz{Y7k 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=:A"aK f,`}
/**************表达式计算器************/I V0bc#W5s-H
#include <stdio.h>8I aN:g,s!F&JV
#include <stdlib.h>
q]bVnzD&d$?(b$Y #include <string.h> vh$XB3e| m,D po
#include <conio.h>xMX(@'vM6i
#include <malloc.h>5w-VaO$U5@b a4H7i

Ki6jTz6YJcf #define STACK_SIZE 100
@{ rO-Q(B-} #define APPEND_SIZE 10 Am+c_9N3sI Jk

w^w0s { I1Ev ~3}O u struct SNode{
8{u(IC&r%Ews     float data; /*存放操作数或者计算结果*/DOYR6v7R*ZG
    char ch; /*存放运算符*/
Q5P`|4c/gPM^ y,H };(SU]gj5wEN
?1^(O0U^ Q8[ S[
struct Stack{;HWsv3o7\s
    SNode *top;
*ZE$n6y#E     SNode *base;
k8g b7}%}$Nf     int size;'V7^"p0q8jE
};N)jn UR

(goQbD5b!M0L1l /*栈操作函数*/
Lh;oU"zM.H f/R3i int InitStack(Stack &S); /*创建栈*//Tc c0^/a'Fw
int DestroyStack(Stack &S); /*销毁栈*/Z*wf {8N8Z
int ClearStack(Stack &S); /*清空栈*/
0a`,C4\GP? g int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/rs0l/Xa+\
int Push(Stack &S,SNode e); /*将结点e压入栈*/[|g]]@y)p
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
!Lt;at1y0_8dV
~1U"kC^ /*表达式计算器相关函数*/
7t.qcKuVW char get_precede(char s,char c); /*判断运算符s和c的优先级*/%pQhTt(|
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/1M.?p6hT+o{ T.~M
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/!Hw3["b'ba0S
float compute(); /*表达式结算器主函数*/
(H6a6{sS:i char *killzero(float result); /*去掉结果后面的0*/
0S'?:N3| W
~J1V)rh,|KF int InitStack(Stack &S)8P1T*s)Y)j@+^:}
{
fU8V.UA?     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
q1OH,L&O w1{     if(S.base==NULL)
9] k1aRp/d,b.D     {
s5]*U_&~B:NM         printf("动态分配内存失败!");
/e3P'tsW         return -1;
VcK;l*K/VM     }^ \-i(T(u
    S.top=S.base;
G6V;qd7b;kat     S.size=STACK_SIZE;;r.T ~ j7V'K0f
    return 0;7Rr"h9uS6Tn D
}'Ng.c"k&zB
Wc*vC?8Y*jt
int DestroyStack(Stack &S)
e d)|+p4b3m.\ {
8u]uCZ [9v)PI     free(S.base);
9L&D ut:{ B:[     return 0;"D0g5YplaW"rl[
}
#Z wwd2K p*aI
UZ-pO | int ClearStack(Stack &S)d(HI.Mp
{
bB~B5v VuKH     S.top=S.base;
-D*\(Nm)u9zl     return 0;
MU)] s X&J$ix }
]y9zN5F|F6P 6|j"O5| F [O
int GetTop(Stack S,SNode &e)
B^#n1Lu [f {@_Z1pe V
    if(S.top==S.base) |+Z[vef
    {G xE&a}{m B}
        printf("栈以为空!");+[Z/i,F\)q
        return -1;l~4p],y%?0j
    }
nm!h-lk3j2BA;F b]     e=*(S.top-1);
*@AK}S4\(R8]     return 0;
M\c)L#h/n]4o V }$H?Q$K| Y
{%tv a?^ep_/i
int Push(Stack &S,SNode e)QK K\$Q9@1e)`I8s
{ x+Nk){3wusm_|
    if(S.top-S.base>=S.size))o/o2q&Oz0O4F
    {
/x `G(z7@8U ]3D         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
(h&j ` o+R+i&bP         if(S.base==NULL)
CjI0E2c*SQ,rT         {6[,L y'r cn"b y0yI3d
            printf("动态分配内存失败!");W v I9?W v$Zs
            return -1;1`+c WS"`HV
        }{8o8UTh
        S.top=S.base+S.size;
WG$Mv5m h!} ?         S.size+=APPEND_SIZE;'oX6yved_lq
    }3]u,q*C1^G2A#K
    *S.top=e;+yHkwZ|*tL
    S.top++;7aBJh V
    return 0;Wo[y-hL ~
}
.i-\q;ZO B ar#Z"j"WaM#x
int Pop(Stack &S,SNode &e)(jXJf.[ b
{a6_q+X1K8T&p(l$G
    if(S.top==S.base)
Je3Zk N d?     {jYM{u^ U-\/Y0Rn
        printf("栈为空!");
T1i/Rgits;y         return -1;
1b(W fh{Y`%jv @N     }$d~C.rw F9e?#V h:P)\
    e=*(S.top-1);
;OSH@H+e H     S.top--;
n6viq/k5B2i `~4^p     return 0;Y`0BCp5~au%hY
}'^wYv)w'U9M

JA{SI;[Z char get_precede(char s,char c)
hO2I WE3MV3i"A6d {#w Z&DO"]h"Z
    switch(s)
B:c6? Bc     {Tl0q Q3n
        case '+':                 'Uu/fs;q f8c1A"f
        case '-':\xp-g9tvH0L
             if(c=='+'||c=='-')
] pQH4bo4}%vq-hj1`                  return '>';_A},ZP7e/bpj
             else if(c=='*'||c=='/') L j'|%N$O Hx
                 return '<';
$} Q8~m-Q)Dt0}E              else if(c=='(')
;r(U2R7C9F-E3X                  return '<'; g7Y0Xs*C4C
             else if(c==')')
XQV(B.nH                  return '>';
%u!P N3r)Z              else 9S'B6UH/x
                 return '>';
:FB,xAL%| g}c`         case '*':{V5Tz*Mx'IU
        case '/':
V%xs3Vc T7T              if(c=='+'||c=='-')
`n G#F9P3Sn                  return '>';
E y|(h Ay              else if(c=='*'||c=='/')
Rj}ot e!P?2H                  return '>';
@ Cs^;W              else if(c=='(')
%U,k K%Q-J}(w Kw                  return '<';p$S!T3`S;C9_ J
             else if(c==')')%R9j,~ `u"h4]
                 return '>';iG;['v1em?{
             else `e6Z ]LGOM&G
                 return '>';
K)vsB @lSy#iG         case '(':'\U(m `z d#H"w!A
             if(c=='+'||c=='-')
:du:|'Q2j`%X8_                  return '<';$A+MtQ$z&SK;hL
             else if(c=='*'||c=='/')
"q1~ ^H%~Px                  return '<';
8i F{"]N:{4Xd              else if(c=='(')
+j*Q3Z!rajV R,W                  return '<';
{X;Cm7x9o9uo5id              else if(c==')'))L)C`8}0v/s7Ly
                 return '=';"L q| v_
             elsex3wu bG4C'{W1}9M
                 return 'E';Z!B3qw4~ O
        case ')':
!l"} N%ux!g              if(c=='+'||c=='-')
s;S#@2ZR                  return '>';)ue%@8Vc G X/B
             else if(c=='*'||c=='/')
J-H)v[C H(\1i]Hj                  return '>';EV/Kch|-T
             else if(c=='(') T?is| |s @
                 return 'E';
J4J{~k nJWrV$z9e              else if(c==')')n.Y+Y?BvPxjD Z
                 return '>';6V2D&iX }%h%oTB/y
             else)d&If+b;c0kt&_ Jx
                 return '>';
kB_\9? j         case '#':+OE1^d g%FcvJ*f
             if(c=='+'||c=='-')ka^&n a3]&J.R0NO
                 return '<';
f6Z4a5m,~              else if(c=='*'||c=='/')/b4Yo ZU
                 return '<';"eq#^DwIvI];F;vw
             else if(c=='(')'ba|9w o,C R[+L
                 return '<';
,_|SNK0W.SC              else if(c==')')
F&dHm8[                  return 'E';
2AxG)S!`V              else} {~ho:g
                 return '=';,{9J?9uL.l9b
        default:0X;] m@a,| P`@GND
             break;cr'\.txgJO
    }
FKu4gW     return 0;    7C~kWd[4X0JW C
}
*N)Sl7Z*OAJ&@ F #lWn Q]:} l
int isOpr(char c)C5X'gx"K
{
&KTl?NBw)j blw0E     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')W~a+fxY8G
        return 0;
tLJ XC4k O1v k_i     else
"P B\f5iX0B3tI         return 1;:~Dd:@&V&LM
}
0H o5y%eQ2Jy.R w)Z|1t-v7b F
float operate(float x, char opr, float y)
Oa)}4`:[2G {
4Q(`'Tnd"`+s9c     float result;(Jj3e]'|1EB
    switch (opr)
%c)P7B7PVq!x [i Q     {"Uz@O&R['ysh
        case '+':
!qY-Rq6m-Y9f              result = x + y;2Hf@T.ggy w~CP
             break;
4W|e s{2RUdVV         case '-':
X0]._ m*T_;h dt"P              result = x - y;\|{!Qo |v1H#O&Q
             break;
:}fe p;xxH.P         case '*':
]/~ y y.} u k B              result = x * y; Q wsU%m,C
             break;IN6FGf}
        case '/':
;EQ7V7_a5u`qf%F              if (y == 0)
Xl Y+L8k7K,_!D              {fI.]AKF(G
                printf("Divided by zero!\n");dS{#z6|2_
                return 0;-Qh,VPT(g7E
             }
)VQP~|K&F              elselci_w5B
             {p {&p%{+aA?1|
                 result = x / y;P"O.[)n|%S
                 break;
(S*n4~@?"i QtSA              }N'Z7s/NJA5e;P~
       default:
:G5J+D:thRWCh              printf("Bad Input.\n"); h Ni+I(VS9`E
             return 0;
1nTh&nf/XE @s3w     }
v1g m:f)j6w/l     return result;
L QK3f'V }QG#e }   
p N#egr 0if7P J!GWL}/w
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
J\M @r {t?X A2r3q[
    Stack optr,opnd;
wm? F7yiR TY     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
0rvo L2h+O'vn     char c;
9F*a0_G1_&Fu4Z.u     char buf[16];6X4Ay)x+d$`h
    int i=0;|K7L\{(Au9l _ J
    Fn8ZS8w0U!S
    InitStack(optr); /*用于寄存运算符*/J,[*Q%s,XD
    InitStack(opnd); /*用于寄存操作数和计算结果*/
/r$cE!S(c mV     memset(buf,0,sizeof(buf));.Rj}]'c,h h
    J-Y3W9hE7_0`z
    printf("Enter your expression:");
O6W)C1h Nr+j)fi         ~ X`^a@5z
    opr_in.ch='#';
G0h r'n3dM     Push(optr,opr_in); /*'#'入栈*/:| H)d T.n:Sc
    GetTop(optr,opr_top);6@6k"SZ-c a^xL
    c=getchar();
!V8D-G!b)E1},u,q     while(c!='='||opr_top.ch!='#')
S?^L xk(P_b M     {} QEj/k%s~"I2Qqw
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
s4q'\sD u.U4l         {wpA7f1P E
            buf[i]=c;
P P,D P5T@?c             i++;
WP'A`scv             c=getchar();
9H5]a3?Q[0b1n         }5y#L-m G9I#M3cq%jL[
        else /*是运算符*/o9_%\ [$H _IfNNT
        {I:fk"V5`8ku,v P
            buf[i]='\0';
O/HLS Q'd             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/@F7V.Y&v_&z
            {7qUMy;V'g#F0u
                 opn_in.data=(float)atof(buf);
1s~6^6Wn;J:T v                  Push(opnd,opn_in); J&B-`4D*zr
                 printf("opnd入栈:[%f]\n",opn_in.data);1k!Qn"E~Gcl j4p
                 i=0;
5mpXD#W"d C O                  memset(buf,0,sizeof(buf));a2LaY5LI]7V U
            }X WYp&D6t~z}?'|
            opr_in.ch=c;
.wWS7sK!W'C             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/%N![~1]_ Do,vg@
            {
%? _5O|`wVl-KP.h                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
_4Cp.z*^3Be                      Push(optr,opr_in);&pNz&E5L0RB-r
                     printf("optr入栈:[%c]\n",opr_in.ch);
+{ldK%ntHF6M                      c=getchar();
}5w}+v]H/I                      break;
D-W-CE4BQ`2tW                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
e#{C3]!@X)J;j                      Pop(optr,e);
nA8W E&Ey                      printf("optr出栈:去掉括号\n");E#O8gH;G(Wn.x A
                     c=getchar();GZi&Y/rK y
                     break;;s$GTa4n
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
x7e({{9C,W l                      Pop(optr,opr_t);
(j#l3n-E8U-c0J g x                      printf("optr出栈:[%c]\n",opr_t.ch); C:t]s9DR5ba,} a
                     if(Pop(opnd,b)<0)
F]9_)f(@Z d O                      {1D%Df"X7K4f"Fq$q
                         printf("Bad Input!\n");
*S2b'F!~u+F                          fflush(stdin);Y"eX!k#D
                         return -1;ac BR+LH s+}.C
                     }
T6\;~!U{{(R Xq                      printf("opnd出栈:[%f]\n",b.data);*nGm pIM#Y
                     if(Pop(opnd,a)<0)1Q3Rafw
                     {
Xv#|:DT*W d1\|                          printf("Bad Input!\n");
6H4]*UC Y;K8F                          fflush(stdin);r{x:B)T%Ow%Wo
                         return -1;
@ ~1C2|8]/ci                      }
r.g\~q7\N                      printf("opnd出栈:[%f]\n",a.data);[V']X4E2s1ay5F@
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
$l\)n#vQ;|$Gs p'E                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/0P']r"Z}g
                     printf("结果入栈:[%f]\n",opn_tmp.data); n5U$w%u8P_y&R]la
                     break;*QZQ S.Pd$gT
            }xR"KLe[
        }J D.W(v5l1LW
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
^h5Px$JeA5?e;j     }
%dAV;i2m^[9J     GetTop(opnd,opn_tmp);
yH+p5hcoyT)] X5k     DestroyStack(optr);
.P NZRI,x#k     DestroyStack(opnd);6azQ P9P FE
    return opn_tmp.data;
Qsp_8xd)H;_ }
2i*[jaG~d6f o:c{q7n,L
char *killzero(char *res,float result)
(^'Sq-yWI e {
B2S3N2}pKMn(Y     int i;9~{f"erDl

\UVF"O_ g6Fy     sprintf(res,"%f",result);
h;Ze/e$e)no~     i=(int)strlen(res)-1;+Xb8t+w|aB3oz
    while(i&&res[i]=='0')7h,Q(j*cwotLm
    {(U_)R oe8| g
        res[i]='\0';
r5x Q%W[L3MiU!J         i--; Bfw)n$B5T4^
    }
_IVj @9T     if(res[i]=='.')\qlpU^&@0|
        res[i]='\0';B j,T/iuq
    return res;
tb.`?@/S&H.u D4i }
$q EF)VF8_
k A\ O5T0LbE int main()
u.R7j` i {
Q!^t'{5H_"g1^ t     char ch;
Y e,h*t;h     char res[64];
sT2t"H;~*W     float result;
/v*JhGmc8P     while(1)+EA`0ZD8V;C Dh?
    {Vx"} V"YdXmP
        result=compute();
)o ROIO;P!j lnt         printf("\nThe result is:%s\n",killzero(res,result));%]:J7Fi ]Ao m{(]
        printf("Do you want to continue(y/n)?:") ;7WM'jl E
        ch=getch();p+Mfd I
        putchar(ch);
%@j%eu@]m X0P         if(ch=='n'||ch=='N')1_ OX/Y(KU8m
            break;@"n9l0@!y.O
        else
K[G ~;wN*|Sa             system("cls");]jKI"M]6m]-A
    }zh X7[MJe
    return 0;5K&m i;C ygZ
}[/i][/i][/i][/i][/i][/i]'[(N N+w)c)??q)R\1p
t*`2}B;o1^
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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