捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
0] iZ"\G0y l 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=?B!Bwk4s$p8c \2r
/**************表达式计算器************/
,q{,T4^.y #include <stdio.h>
O`_4K]zj9J9k3NX #include <stdlib.h>~7@-GpH*Yq}
#include <string.h>
q,?x5t(\L6x z)n #include <conio.h>%R-w"hU3w j)j
#include <malloc.h>
F0CTX_!BN
2BY3h$lL sA7l #define STACK_SIZE 100
W1h\(\@ #define APPEND_SIZE 10r C#oh|K%|

? G,\0S|.J)YS struct SNode{
i2] O:m:a2lc     float data; /*存放操作数或者计算结果*/
1c*zN%@tG     char ch; /*存放运算符*/
0II-b+llw };
1Al[|0w:ML
z2{6DvoH!W(v struct Stack{
l3?AOv     SNode *top; iD1k9\%|:nT v#q
    SNode *base;M8s2CP5j[nIo)Q
    int size;B$PU:g5y-r#a
};
b'?/mo$^+mF*L MBQ Ph_}
/*栈操作函数*/
wn3j9G"p1g1u } int InitStack(Stack &S); /*创建栈*/^Z(zGG)k ?
int DestroyStack(Stack &S); /*销毁栈*/
2p4i/E8ep8O int ClearStack(Stack &S); /*清空栈*/
s8A;vz-C4SK int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ sJ2?2k$E1J
int Push(Stack &S,SNode e); /*将结点e压入栈*/
w2VQU*m SG int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/_&A#z ^O N6G5P
\1G;I s_8\7I{ R ewQ3R
/*表达式计算器相关函数*/
%pot] I"F5uj!V[ char get_precede(char s,char c); /*判断运算符s和c的优先级*/
hW\Zl [/x J#Pr int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/a6xXg.{
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
b;Xl l9V IF"} l float compute(); /*表达式结算器主函数*/0nz'\1v]'bH
char *killzero(float result); /*去掉结果后面的0*/ vu O4I"R
1g/@Y$? w/A ?
int InitStack(Stack &S)
5K ~&y\%X {
]9k5P^c%Sk|     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));l3m0j~H@
    if(S.base==NULL)
Y+KQA`6k%H     {sUo,^xoR
        printf("动态分配内存失败!");%f4hi6H8X-`h#{W
        return -1;:ag%F3_k9Tw
    }
-M@e#O0F'[     S.top=S.base;+gY:R!d8s2Tq+H
    S.size=STACK_SIZE;9J[)nncg
    return 0;
3?]D:t)C"lB }
C3aE+v7^"b V)SFt"Y$m8a
int DestroyStack(Stack &S):l5E?#b5hH5gb
{
2m |R;N#p UZ{$i     free(S.base); fv3Gy%{
    return 0;
X\q(m:hXz }$s(W,d&AC#E K

1r}1ApJ(G.U:S S int ClearStack(Stack &S)
#E#Hz b o u/K {
7[f4[-fw$pA     S.top=S.base;0Ne$PU+ef Y
    return 0;0~]rr|*l?3J
}
K:S}4Ls1Mp-c
9~:oo G6AN int GetTop(Stack S,SNode &e)/rG9D*p(z1R7{3}%lE
{F8P8UU_!zM9p
    if(S.top==S.base)d \ wb,x]Dr`k
    {
wm'Bc/\e6W D%I`3H         printf("栈以为空!");
4s6j3^ Vv-G0e&t+a         return -1;
h'{7sry     }
;_p V"l}9}z1X     e=*(S.top-1);/j d }M ` {U
    return 0;
K i E"V-J'D.~U:~ }
C c t[t 8zmI FU(^P,]
int Push(Stack &S,SNode e)
C8akD8E^1I;S {
F)N @p;{HN#r8W     if(S.top-S.base>=S.size)
,ZdN Pj K?&N     {
8R{(F3U\ J         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));e#{~?O!i
        if(S.base==NULL) a;C~Di3~
        {
*K[ r Qw!]6g1d             printf("动态分配内存失败!");
$[7WO%N8A| kJ             return -1;:UV.q {'M%xA/m8B/w
        }
xs.N'o*gev         S.top=S.base+S.size;1^E{Q Sg"lg c
        S.size+=APPEND_SIZE;
Ma0R$vb{gE&j     }&G I%zwE Se[{8D
    *S.top=e;
I Ol{%k1u#Q     S.top++;8q-Z\Oa"H @8Ih gIS
    return 0;7~[;WA@7m
}
HV6Y S@ q(A0R
D^W3Rf t3j,Q4r int Pop(Stack &S,SNode &e)
)ac,^@;Q)f3[Z {
Qt0R\,Z     if(S.top==S.base)
'yD4F f&{'C     {
4KD CBT)MG8w h         printf("栈为空!");&lF}:s4D/d3o\s
        return -1;
-o }-xS_AX3Q/s.o,z     }
k Q KW#_     e=*(S.top-1);+]"c'l6lL;^J
    S.top--;P'BR%q-O-VUB
    return 0;W9dA"Zz6D'|
};k;nP1K Y$^W_^@

`-Es9DZ8v F char get_precede(char s,char c))^'kHd*\j
{
;t#J5sH'N&Fj6Qz     switch(s)"Ar'RX(j.F0pd;`
    { Q(km|t[{8a'|m
        case '+':                 L~1KP v!^7a|
        case '-':zP6KH0YbkMY
             if(c=='+'||c=='-')
x u[ L?H,W K                  return '>';k2K N*P DYLl&f
             else if(c=='*'||c=='/')
%x0bF7H gJ#\                  return '<';*L%x1wa2k/]\/XE
             else if(c=='(')
[1C {4X FQ.F+\8~Yx                  return '<'; J4b:Ya!? z
             else if(c==')') k\K(?}e%k
                 return '>';
J\(Zfh+?              else
PRPm/o4_s2f^                  return '>';
mD)_1K1T5M*hw         case '*':'Av#m(^+Qq)R^X
        case '/':
V7cQ;d{.u+Q              if(c=='+'||c=='-')lav AL9s,K'|
                 return '>';u8oN `K K,r1K
             else if(c=='*'||c=='/')
&v0{j$a"[                  return '>';0S-\0h&wfY/bC
             else if(c=='(')9ABv pu'Z9v4D1I9s
                 return '<'; ^BW#AX
             else if(c==')')
,i5L/uj D                  return '>';
i It&X C:A4s              elsez0d,rx-UA)C Wx2c
                 return '>';
ayAj7tAk y$j\         case '(':
_-Iy"vp^2o-n              if(c=='+'||c=='-')
bO(d _o V.`%[ ^LP1O|                  return '<';Z3g jY eVN
             else if(c=='*'||c=='/')
4J OCFxIMG|(OP                  return '<';wm4p;d3MfkK
             else if(c=='(')
dE2bR%\;r+@s:u3pk                  return '<';
UUc+~)`x              else if(c==')')+yL5]j/}&e9v ][
                 return '=';!h8fF&B8[_)Ne-DP6T
             else3iGE|{}!rl
                 return 'E';3K@ D |M4d%HN
        case ')':0v ?e[&v\3g)pJ
             if(c=='+'||c=='-');Kg.]-ArQ"t;|o
                 return '>'; k,Q||QWdQ
             else if(c=='*'||c=='/')
&|_)Y3P8b4D,k*u T8?0@                  return '>';
nu | a5H nMh1g$W              else if(c=='(')
D*k^#?:v9syQ9x                  return 'E'; To ^%lg:p'[KiZ
             else if(c==')')3l v_GpXni
                 return '>'; m}Ii9P-l M-Qf V
             else1vP]#IB$ue%w
                 return '>';!J\F(\
        case '#':
|2l*G5E-k2v2W              if(c=='+'||c=='-')
;C JXx4F3Wc$q%s                  return '<';
&{3OtHjL              else if(c=='*'||c=='/')
!J;b2B]q,F7U                  return '<';
5z5oT+|l K v a5L*c              else if(c=='(')
*A,Ik:]$W                  return '<';S l3q3n$Rz:c.y
             else if(c==')')
,M vfL#MC5q                  return 'E';3i-b.b)`Q
             else
!FG8V^;x,i s%n+?%hD                  return '=';W,QT kx!D8b
        default:
Gz#Q d p UDM:b              break;^hI5X7rs3jZ
    }yX&lM w#F
    return 0;   
v+h?||"KP*U }{4u2E9n'x gO
.UVC(H;^._ s3yQ"M
int isOpr(char c)
c MDz'Y.bI+s` {
't`(V5fYB-ih8y     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
"gSqu1F+i         return 0;
B8tpI1dv7E`4~     else
}["^6i{`         return 1;
;_t"`JiqOu } gC]Th Fi
Yvo"uioD
float operate(float x, char opr, float y)gc#N;g8U;e
{tA2mZa/X8n mA
    float result;
R(V$D0n~2Z m     switch (opr)
0b:N@#m[s%Oq/k     {
J;hrq Oy1`f7Qa         case '+': n*QJ%R${OE#T
             result = x + y;
k7oB |1| z              break;
OucM3\         case '-':
Tp4hS-wG              result = x - y;*d+| Y#h-E-~
             break;
ga y m"?!n7Ol         case '*':
y-a B*V D-g              result = x * y;MrD(|5N3t(z {6m"o|
             break;"Sw+Q2^/je6Q
        case '/':
ik+b9A`^              if (y == 0)
nM'[3J ` i"^j I              {.}fqp0Hr
                printf("Divided by zero!\n");Gh J T)FaG
                return 0;
N'ML3lF#R              }
U%c'u K_%|              else Z },gMV m L}
             {
*}dho{ K.j6`                  result = x / y;
kc+b'EQ3}                  break;
6m+Yl/H9tZp              }&jR6Ioc`,TY
       default: ?[!`"vd#wZ/H jM
             printf("Bad Input.\n");
SE$}%l:wh-h              return 0;:cFP7ER
    }8e7mlXI)Fq(s
    return result;Zz^;ht|]
}    d+x"}T6UN
F:` Y.} v~^ \
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
S\s6R%]7v {
lx UB q*xHG     Stack optr,opnd;
W*k$qH |zX+EJh c     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
5| \\u pkM     char c;0}S1h1kB ~
    char buf[16];3R2m,dM FtK-C]
    int i=0;eCC&pt5W
   
4]D5f1nX I!t[;|     InitStack(optr); /*用于寄存运算符*/
zfQO/MK%VX     InitStack(opnd); /*用于寄存操作数和计算结果*/
1s j7A&q o3u$F#Lp     memset(buf,0,sizeof(buf));(Ly ze\
    +W|mv E)d
    printf("Enter your expression:");
2\0Rew3L*T#c         
tU*s5PfT     opr_in.ch='#';4a S#Yz)n/v6Sj
    Push(optr,opr_in); /*'#'入栈*/
g JbL[!@ZG~.^     GetTop(optr,opr_top);
v9u5N \n A/@     c=getchar();
FJ2~Q\I     while(c!='='||opr_top.ch!='#')
P3pd0rme"`Y     {!e*l(^/Y2e\
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*//y8TF(Y4fw)? j4c AL
        {
Z1TY\4r+GO             buf[i]=c;,V0|8L/U.Y+n9o%P4P
            i++;
xJo C-eo0Tk1n             c=getchar();k8ClxI\I Wgc
        }D`L2N$mm k
        else /*是运算符*/
#j1C{1oRA5SUCw8F         {
R_ Q9S.Uy5G D#B             buf[i]='\0'; Q!]_ T,i
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/,V%jYHV:X8p8G
            {
l-ht zl ~t:LSGP}y                  opn_in.data=(float)atof(buf);4z-Q\4q5@S:C
                 Push(opnd,opn_in);Xo^)g+T
                 printf("opnd入栈:[%f]\n",opn_in.data);
7N Ol V\$w/e4~                  i=0;VTpA#xuR[wz
                 memset(buf,0,sizeof(buf));3s%F5jgP
            }
)fA hE*`8y             opr_in.ch=c;}B7am KM^/ZyRyF
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/j'[zP'n{`
            {
ult/\iAE                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
%x&K7Uq@ QB                      Push(optr,opr_in);c&h f:] h%RJ;f
                     printf("optr入栈:[%c]\n",opr_in.ch);
]RkBu"_GO                      c=getchar();j1{2Y}7Yf
                     break;0['O+zJqzx8c
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
#C(S2BP-I&a1d!E                      Pop(optr,e);
T@` B1hW`g Ci[                      printf("optr出栈:去掉括号\n");F6}n }sci
                     c=getchar();{9^6TM[i D yG
                     break;
(Z&l&w0h"H0e                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
|(c@x)C P$}Qm&zq                      Pop(optr,opr_t);WD3c,aL'k~J_1rej
                     printf("optr出栈:[%c]\n",opr_t.ch);
"a2p S wNA;K;H                      if(Pop(opnd,b)<0)!`7M6E7YM
                     {)SAr:_V|YnR
                         printf("Bad Input!\n"); UG(]6q d9G/z
                         fflush(stdin);&OI.xVE}q"?yu
                         return -1;
&I6m|8U(t_&rMEZ                      }Mf6c0J+C E
                     printf("opnd出栈:[%f]\n",b.data);
v4gvzD2q                      if(Pop(opnd,a)<0)1x+C])K0k!A6[
                     {bMOCixIhQkb
                         printf("Bad Input!\n");8vg"[%yP
                         fflush(stdin);
LFoO `/Byt/\                          return -1;P&ac7K@S
                     })dFx-V7a
                     printf("opnd出栈:[%f]\n",a.data);:d8@"l5s0vc d+U!ykY
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
l5^9kbC7kJsp)e$O                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
*}a_3Fmz2f2S                      printf("结果入栈:[%f]\n",opn_tmp.data);
w5J U#Y4Ae:Vl x+_(Ee                      break;
/t2j Y&Bctegf7j/@             }8u1e,`+c@
        }
jcTr k$r;~[1G         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                t7K'Q G6}k
    }
&\E @?sW ^     GetTop(opnd,opn_tmp);%dW+n2n@{!qAp
    DestroyStack(optr);
1d8[XC"sa/fZA8K     DestroyStack(opnd);
9~ZbFt^     return opn_tmp.data;IP awd+}
} X'{4d#mQ
.RC:O@3{.w
char *killzero(char *res,float result)
gJ7cws[1I` {
V6i6ZgN D     int i;
M#}:eL/L&}
A;p N.[ X-wk     sprintf(res,"%f",result);"L'p#E7}D bL1u\U3c
    i=(int)strlen(res)-1;
t'qp:p%`A     while(i&&res[i]=='0')j:xH J4V+B7L5DC
    {.^*C:]z]|q
        res[i]='\0';;M&f-y z!LOZa.C
        i--;7E;P%BW9f5Ex
    }
u1G s0['QQ     if(res[i]=='.')
6Nc#c'q3\9sY b4t         res[i]='\0';
CC|Ff9]D     return res;
*rC LF'v h } f(})q]:Jt dG

7o*T_Z r9F#V$B int main()/F{.z:w5Ko G+S8z
{z"U6p2})?\5gm
    char ch;
tL6t0H&{l#w U     char res[64];
.\p.d:~ p`/Mlp     float result;
0n-PuL%a     while(1)
W?U+nJzH     {
z)F1H?$X         result=compute();
4xT-`G1lN'knH.y         printf("\nThe result is:%s\n",killzero(res,result));v;cT2f/l,O1ro+`
        printf("Do you want to continue(y/n)?:") ;
i/t:@XYq-V0]9D         ch=getch();$C ]*SnkR}
        putchar(ch);c1M MF%T
        if(ch=='n'||ch=='N')
^4c$v-aM$d             break;!s3Kg+e'J{%{
        else
)AayY-p)tp             system("cls");
:N,j_V Q7Q3A     } K;{3YR$iD5Y
    return 0;)e8{6d5cAV:D,~
}[/i][/i][/i][/i][/i][/i]
k ?A#RL.rC Prk +d~-nW_ d8L
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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