捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.U7y9SV'F,^o"j[
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=5nM5Bq_7vd&?
/**************表达式计算器************/b&ha0E;k,\S8j
#include <stdio.h>+^Nh#S7T*g.E
#include <stdlib.h>.N,Kga0x
#include <string.h> VM [4S g4rF
#include <conio.h>
{/v6A3qk5nlg #include <malloc.h>
2x'p)f!L]X5\+C`4x
U sp0C'G`D#K #define STACK_SIZE 100C0x!n ?8W)s!]\
#define APPEND_SIZE 10d(a/R{-['oW

B-?:d2mB)bH Z struct SNode{
x^/eU a#G     float data; /*存放操作数或者计算结果*/3CH8~+fN.bsH#`
    char ch; /*存放运算符*/ws3|1k g0{ZP S%Z
};
(mQ{@.JC(};v
+Q7Y.eA%R|"p.B;?5K struct Stack{
~"`a;kGZZ     SNode *top;
6h(k q,@ S!W M     SNode *base;
X8\)Nj5l     int size;
1~$^?q+|[ };I0O}_,]7G g Y*ax
~n(LNI)YFsdZ C
/*栈操作函数*/j _&S)~&b Q~vZ9k
int InitStack(Stack &S); /*创建栈*/CmLc&{ P.@weM.[
int DestroyStack(Stack &S); /*销毁栈*/K)j+bA/q
int ClearStack(Stack &S); /*清空栈*/
1f }2G@G(?/mb}$} int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
7P;Dj&h"WO9V8v1d int Push(Stack &S,SNode e); /*将结点e压入栈*/ O't7@V f
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
'du)](yu8V n
J+K8R3X9kaM*i /*表达式计算器相关函数*/y9Y%M ~3y.N)f
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
+TS BYqu7Wy int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
F-v9gv6V"M$JR float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
Q(G0wQ,L5U@%U float compute(); /*表达式结算器主函数*/1[E^#aws5z
char *killzero(float result); /*去掉结果后面的0*/
JNi"RHHe4r+ab H3g3w R2\P l_&V
int InitStack(Stack &S)
h Z \!MK_S EH {
o(mu]p&Ld1w{![     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
;C kJ \gKN3y     if(S.base==NULL)
e%F4aaBL     {S Tt$L {{S;M
        printf("动态分配内存失败!");H4VH vBB
        return -1;7]J0BJ+U
    }
n2m4{U y     S.top=S.base;
tW%x'a#mXA#Oq     S.size=STACK_SIZE;'B G3@1D|
    return 0;
(W HHM%[s8N }
H uw8uL,U'a
:p6U/no9eH Bf1e int DestroyStack(Stack &S)5h,a:|MXK }
{
xQ5`6h^F*l     free(S.base); B%GD\gV#O
    return 0;,q6}Y6[N5jK#L{ h
}
-X.Q+OH+v4txU
nxk?5n+W#AKzE+[ int ClearStack(Stack &S)Ma%m:u%|1g
{
9mHh8{o.u     S.top=S.base;
.cY4p,W]_l     return 0;Z0N| M!m]I8hsX2y
}
V;Z2~Rf9wRu IbnqQ2~+j$|:Q
int GetTop(Stack S,SNode &e)*cR-ke ?e'``
{
o;Na7yW&}g/k     if(S.top==S.base)
&L[v3KlBL_     {
W6X.Xi'STh;B*ek         printf("栈以为空!");
%X5u#Hb `         return -1;
-|q?5}R q;Q l!Q0x     }?e&q X:w7B8d1i
    e=*(S.top-1);Z:G:uf\ O$Z%p Pr
    return 0;
W0l sV!QG$tw }
)m$QM m.U+]w]0H0_w
xc#IBG int Push(Stack &S,SNode e){X mI/@P;{/y B
{
DF![ E5H[6f     if(S.top-S.base>=S.size)
9?R&w$x6];l5w0Y%ESl     {
3AU'C(N,p0[;W m9\         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
@0V0p\)t9F9_1G,^         if(S.base==NULL)
gq-gALxk/C ~         {
h$ca;e"?5f             printf("动态分配内存失败!");
+F&r)j4VGL             return -1;/_Z(xsaIY
        }!v9Y1U;jfF$i
        S.top=S.base+S.size;
5t6UhR6h V.o~3}         S.size+=APPEND_SIZE; su*\u0yB#jCojyO
    }L2K4K,]fr
    *S.top=e;
ea2Q4|']Lc y     S.top++;
6O V3i`*[iH     return 0;r4kd+`S-g3Q;zK
}i#P'~g+me0lq0F
Yl.e#_:F }5EmJH
int Pop(Stack &S,SNode &e)
2TB1LT"S8o[ {
&P0p_2B&sz&c     if(S.top==S.base)
,WY4|-E~0H     {bds@cV1K
        printf("栈为空!"); x%v} wIX:ip
        return -1;
)R`ey1Z$G     }~#X[ \{(lQ
    e=*(S.top-1);
SAW[7L aB     S.top--;
3C-v O-r?     return 0;
^Z z(e\:{9O | }
nNz t*J_2E q*|g'~[ yhlP0v
char get_precede(char s,char c)z2LG,R2h*g D@
{FB O&vXQ#x
    switch(s)
W5k,l a bH&`Ey:o!}     {
+K4cS%juz.]         case '+':                 /H(s8U@ \hrc"C M
        case '-':
%Jw E_JI$s              if(c=='+'||c=='-') N/[R!Uhw*z\4],X
                 return '>';4uRCbOE Jd
             else if(c=='*'||c=='/')'cR}!Z+__ p-{
                 return '<';lM!S Kq`j w
             else if(c=='(')
l6X8H@ W'D9F                  return '<';4|&cn6Ry
             else if(c==')')
Td+c1V0G[6a                  return '>';
l~-f2KKS#qr)rj              else
.]9g G yn                  return '>';u5f9gS\-K%n j E
        case '*':0at)a[1SXV
        case '/':'g#B [-} mS{
             if(c=='+'||c=='-'),B+]9g*Y,hL4U"agZ$O&H
                 return '>';"vxa7d,nc
             else if(c=='*'||c=='/')"v:tXG0s{.QaH
                 return '>';7^ x!cor;J;Z(C
             else if(c=='(').c{3f FZcR
                 return '<';jGFN"F
             else if(c==')')_ K8]w)O+a9[{
                 return '>';]R$J/eRxC:K7I
             else};x3O6y|
                 return '>';
Vge Ya&[ U.Ix         case '(':
;CjY d J)g;Uf              if(c=='+'||c=='-')
nEb2sgTx                  return '<';
N,^D2m7RQ5YDm              else if(c=='*'||c=='/')
U6r?UpANJ|                  return '<';
-v,d\;h[3C`@XI x-G              else if(c=='(')c EMZ/z.rcDd
                 return '<';
8A X&Q @:OuJ              else if(c==')')h$^(A?]|5`pZ.p
                 return '=';9xyET6A6mlJ
             else
-E u|a5HSi[                  return 'E';
/j Dq7WK OYP         case ')':3C:{Z&J2O
             if(c=='+'||c=='-')
}7`4k z)u2pu7M%Y                  return '>';
+P"`,K^ WS ['u"k              else if(c=='*'||c=='/')
&yA FaVM-z                  return '>';
s)N%UTE6Ee              else if(c=='(')
.C7Sjr@                  return 'E';-C1]/j!P Wb,|
             else if(c==')') J I-a6p2oQ%j.@T
                 return '>';
w6I.mRP*r;~;~-r.aD              else
#`V*Pm Z8ciBgo8p?                  return '>';
;Q1K!r}@"~'x         case '#':-AN#vj"}'c?c
             if(c=='+'||c=='-')H'un)G `/Nk"V9S
                 return '<';
1@-r1x*DB;B              else if(c=='*'||c=='/')Q)fi#f2i I
                 return '<';lT_ Rx OX
             else if(c=='(')1kro y4JE
                 return '<';C*r o9n.\V]
             else if(c==')')
U]E:g y"l C5L+TR)j                  return 'E';
s} T1\9[8]5zW2y              else
IN6K"`,O(Z,x L B2W q)B                  return '=';Z5LBo5\ a&rTm0O
        default:
Q5j kD/AXS&V"l              break;`.n"a0XwO
    }
$~/P?)x1{B3g     return 0;   
6b;bE-nT!JQ }.b G-g$EL'I{)oy3Uw

wF w eE;Ll int isOpr(char c)}&xA!?%e
{$dc&d(f-j{6@
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
7V+B!K!`"u g'm         return 0;
'SD"r B2d(y     else
BRUeLIW V         return 1;%Hm;S,xz9aX0rQ
}
K3vqD1u/k+A| o
H\9x8y[L d7l float operate(float x, char opr, float y)nN,Ho'tdaCB
{9`PZ9c z-sHN!i'`
    float result;K9QC%v+f \*go%B
    switch (opr):I5j5l)\;d8a[|k
    {-V8G(x h0g:OQv4x0A
        case '+':
#IR n(E f{Z              result = x + y; w2q9tg*p'r5N
             break;1sH(x:J+VC
        case '-': Zl I%mo*T/o
             result = x - y;;qI(^#B_:p
             break;
e0DC j1g O         case '*':
1STew:Xkjon,K              result = x * y;p F{E0L$eb1X
             break;
z8Yz6C^         case '/':
V Bs%{3z9~ ]:|              if (y == 0)$O e#MUPH5nPy3X#i
             {,OupF8g,E/],_9P
                printf("Divided by zero!\n");
B5MI#Z*f;Ry1W(D-z?(D                 return 0;%J qd&j6P [;a
             }
h3M/o!l6q9V+Hk              else
\:h Tr3K1s!^F              {kO$W yV?#da
                 result = x / y;_R xo.i4?5}'R
                 break;0_x E o,B
             }
/j&K\[*Q        default:
|,Eb-Or9sq,C?              printf("Bad Input.\n");
} sv8N)H;O%m ~              return 0;
$@v5xCs*Y     }
5y/|"N fM-e,l,e     return result;
tHTp u'z6c+p }   
whw5YAw
8g6H#pgj*l:`1s!\ float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/B;n(?9|5q'p@'sDVX
{7S1w"k?.^dz;n2E
    Stack optr,opnd;3`8Yd M6b
    struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
!p U*\+R+vp#X6a7J(J T     char c;4d6OG'\TXH)ZU7Q;a
    char buf[16];
x*i#B^q*Gv/L     int i=0;
+e,~'Oz4m.X    
6VF!r+oYq s}!W0C     InitStack(optr); /*用于寄存运算符*/
Z;e6c6l8Pc     InitStack(opnd); /*用于寄存操作数和计算结果*/
"WR9s({8U,Y1k3pNh     memset(buf,0,sizeof(buf));!z!L u.c k l n
    x+\1W"`*f:J
    printf("Enter your expression:");O)T*a$bE,~k'D r
        
s)X/Bh5yf$Zg#^(S     opr_in.ch='#';
#ziY*wU"h_2l     Push(optr,opr_in); /*'#'入栈*/%DL oD0C)I*]
    GetTop(optr,opr_top);
B7Cvz.CL xbk5r:M!m     c=getchar();
.VM(rQ1W&P1syP7s     while(c!='='||opr_top.ch!='#')/j0IL Nv ]
    {2y+c/`x} TR
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/V*^S{KD/fN;s P:[
        {0k+L.jW*q
            buf[i]=c;0Ri6D j$P7eVY n
            i++;
&qA)P(Nr8r*}             c=getchar();/D;QP;E"W$^b#w
        }9d$TJ[7ul6yDA7~
        else /*是运算符*/ \pj,CEA9]/O/z
        {7@5DA f"W
            buf[i]='\0';
EB6x'S7H             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/uw!S Pya8g i
            {
g4o-~xk-b Pb                  opn_in.data=(float)atof(buf);&eg%N qp
                 Push(opnd,opn_in);
iP&I4O"\                  printf("opnd入栈:[%f]\n",opn_in.data);
Oyy5R[,OH#f                  i=0; `P q'r;p|@Q
                 memset(buf,0,sizeof(buf));3b}YlUG
            }JY)Yz#Ih/v De
            opr_in.ch=c;
R,s`,{;H L^             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/n(d0uKk+P,n
            {
U{4r-ghUB@_)P)U                 case '<': /*优先级小于栈顶结点,则运算符入栈*/ zh(X$d$S!we
                     Push(optr,opr_in);
N a itskcT7|+faY                      printf("optr入栈:[%c]\n",opr_in.ch);
i&O5L#n)M Mt                      c=getchar();
+eH7[-N#cuQ                      break;
8pF/\)q Dz7T                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/AUSm5Q~R @
                     Pop(optr,e);
xOZ U3UE J:]H                      printf("optr出栈:去掉括号\n");c p&B{{9E8P-RQg
                     c=getchar();
4K!h#A+S^S&Z,z _                      break;
[(T4X`}                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
is7SK_Fle E%N                      Pop(optr,opr_t);
qjl YJ                      printf("optr出栈:[%c]\n",opr_t.ch); _p%d-m{ ]
                     if(Pop(opnd,b)<0)
8`Pf q#YS}x                      {6flI/`Z8y DL]
                         printf("Bad Input!\n");zp9U+Wm*f
                         fflush(stdin);
{!oyeDc#q,x,J                          return -1;A8{S e%N T
                     }
3c!E9]t2V drn ~                      printf("opnd出栈:[%f]\n",b.data);-]@N3~5X0D0|0| G`
                     if(Pop(opnd,a)<0)$qnJ VO-c I
                     {9zJ/t!Bn"IXo(p
                         printf("Bad Input!\n");
Kv(I%B;k\ @                          fflush(stdin);
([*CW:NOz"M%k'A N\                          return -1;
3a8ab[&cT7Y"pNK                      }
7QNV+T#n2w                      printf("opnd出栈:[%f]\n",a.data);b#b1u.ce'`
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
%bV1~*sS)q                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
:B5y l!ZT                      printf("结果入栈:[%f]\n",opn_tmp.data);
R)lh[;d0Znz`\                      break;So5CHY;i-h
            }/ke j ~ X }X
        }6s)q\ l H&Jug K
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                XE~TIi5A2s8k3Y3C
    }
xH+C#eq1x#A     GetTop(opnd,opn_tmp);(~c9C2^N#Tk
    DestroyStack(optr);M6vd_h V R([)w
    DestroyStack(opnd);
bfqD6rb     return opn_tmp.data;
(`!q2HoQ8u%wBD6l9\%s }
:QVD'g5j.Ww 4T]1Z+w.H{)J
char *killzero(char *res,float result)-P&fpo TW(~"i
{
k%P8pmu,}     int i;3I}/s:H:Q;?

LBV/\7d"CIH     sprintf(res,"%f",result);
FD^s2]h|J&f     i=(int)strlen(res)-1;
/z]ysn8l&}1w     while(i&&res[i]=='0')
#Au4Td2VJ%\ H     {"D:T2n?Y(f6a4FV
        res[i]='\0';:Z*Kd.w,HR2D#bW
        i--;
^9@1@0^a-CR!xG8P     } yD Y9T!Z8s8fe3Ag
    if(res[i]=='.')
2E,VRc a)q1`         res[i]='\0';
{)cQ}e/^     return res;9B%Xqqoy2a d)^O+J:|
}-M:v^5o'^ h

g/v#} [EU"E i int main()~ \ M|,^
{
&ly4y9C!\%|     char ch;
wF{X7jGnVL     char res[64];
1p6w@9B!CZ!Y     float result;
2gVQ9O4Jx     while(1)h \v.`/nrpQ9Cu
    { VS%cU;cF
        result=compute();
abL5Z }         printf("\nThe result is:%s\n",killzero(res,result));YdT8A"K(n]H
        printf("Do you want to continue(y/n)?:") ; `t w)S3i8R-YwiT
        ch=getch();W Y+Q.sh]s E
        putchar(ch);;D;JOe gf1T nY
        if(ch=='n'||ch=='N')
.o F/u ?0V;[;]*?             break;3[,o/z-lv1L U3L.m3QX
        else3Y4Nc;~0[(pU z!{
            system("cls");
{-T4j(A)?!aZ     }Wc`Om4Uo,D
    return 0;
*x^S&mU4^.Q }[/i][/i][/i][/i][/i][/i]
%~m;xv2?'n5Q 0ad fE$T:oV"kp
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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