捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
ML3U5Ap]'p6rC 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)="[zzr-GWU'az"D[
/**************表达式计算器************/s q]!j1]@1D8z
#include <stdio.h>'d,RycwN j+m
#include <stdlib.h>/V3E7HqhZ
#include <string.h>^ ro2Z}~-P+x
#include <conio.h>
Z3S,S"M+p!W!m2Vf #include <malloc.h>3Ch^~,x)?u)T
N\o!L x+B5|u
#define STACK_SIZE 100$V:QCHH1T/v
#define APPEND_SIZE 10ZO,HHbp
;["`!I(C1N1cjI)xk!V
struct SNode{*E!lEj k!B)X
    float data; /*存放操作数或者计算结果*/
L Eb Z%k7u"Xg     char ch; /*存放运算符*/
.iuWa+} p!_r };4a,zu&xKn
.RV o,r'g ~5M
struct Stack{ |'uPc9|/f'w
    SNode *top;p7D6~*A? [.N#~d
    SNode *base;
|9?:hM6u6dY`     int size;
-at&{;Q]+|*Kg };N)?"z+fj
ns[7_h xko.s{
/*栈操作函数*/w1ZH*z0` w'x&{2f
int InitStack(Stack &S); /*创建栈*/ {+\!e&c6z2e'LT
int DestroyStack(Stack &S); /*销毁栈*/w+bMO)Yy+@
int ClearStack(Stack &S); /*清空栈*/A q8quF(ij6jw
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
#R)e kFXx int Push(Stack &S,SNode e); /*将结点e压入栈*/
M+Y$bjM9Ki int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
6}.ojU|SRc
1~(J,} [IN9G#K /*表达式计算器相关函数*/fc }Q1I&AB;x%M+Z
char get_precede(char s,char c); /*判断运算符s和c的优先级*/ F@~7b%p:e:U YeY
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ hHA.z&C~&m!\
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3NZB+F!d
float compute(); /*表达式结算器主函数*/({ nM9c}+O q.r
char *killzero(float result); /*去掉结果后面的0*/
%zG U+n;q*\joz
2k\B6Fq.S9z/w%f int InitStack(Stack &S)
&U%eC,HqZ {
\Os LWyA2z&h ^+U     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
&`'^1df{k     if(S.base==NULL)gDV?`2Y UA
    {8w1G&]bh ?$[9H
        printf("动态分配内存失败!");"l g.fe!e3`j
        return -1;a'|9lHB Z n
    }
`&M)S(AOdn R     S.top=S.base;
Y8o9w&BK#X!I}     S.size=STACK_SIZE;
,DMU$D#X J]     return 0;:KM&a]:n En
}'}SA6d]+Dy

(n2l%}9A,ol4J int DestroyStack(Stack &S)Zr{{)L6EpD
{
1yV1xxH)a}     free(S.base);
;C Qk%K{$S`~     return 0;
%\0E2z*^ An5~$| } fk8\3L+@+MC`
@Ey!Ha5T r
int ClearStack(Stack &S)
XAoGq"h&f {
8m9EMzeZg6X j     S.top=S.base;
.f1?\8q fo6`H0b&OV     return 0;-|@["}3^f"zya1c
}
8xSF#?&Sx Ue2k +u2},U7M8q@c&{a
int GetTop(Stack S,SNode &e):j(I0]mVESA`
{r-bX1JV
    if(S.top==S.base)
-d'u;x:CMJ-L^9c     {
hn:De I V4B         printf("栈以为空!");B/T&? ^v
        return -1;@i0_i,r4tM,s`
    }
yT4YEzc%D$p.\     e=*(S.top-1);
7\_xl%[t:L     return 0;$VUb#ABb)R
}
F&x Jzl;W p6w'Cv{
int Push(Stack &S,SNode e)ER2U8_?
{ niwei+nRIw)t Z
    if(S.top-S.base>=S.size)'d|h~g
    {1p"e4Wu3oE
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
5c2s.RTd jNGTJ         if(S.base==NULL)}e1Yv#g3RJ T*B
        {
|,p;Q2B W_R P$k             printf("动态分配内存失败!");
C|i0D^] G6L             return -1;
/D2B+Mz)jT\@(_)A         }1ZyO7`,gm
        S.top=S.base+S.size;
L'p S7J[R         S.size+=APPEND_SIZE;
6?%n1IL#?G i-n     }m%OWh5A;pYW0m
    *S.top=e;
B/o/T0B J(J U     S.top++;G7E2u Q ue
    return 0;y Q5X/B+B4`o
}v'z0ksR3^hZ

DX8j*}3P)K J int Pop(Stack &S,SNode &e)3x!c?x6?9g'U(s A
{
2I/D!o6H3ko)xX1~     if(S.top==S.base)
u,Tl/P9zJ1},x     {!R']FYWy
        printf("栈为空!");
VpD~z-o         return -1;
I6W;O_ o!tCO     }tOPLfD
    e=*(S.top-1);
Qn4Gc`-h;R O8E0E     S.top--;
1oN4Wsz.D]     return 0;X%sxNI#f:sT
}
-} mX-]0^ *d o{f.zY/M
char get_precede(char s,char c)
{V'v~rES {
_ oB&ls U)B1WP$w     switch(s)
wL)v*gIG!}     {
lJ.vbfk)T9u         case '+':                 :l5~F }!l O'\~N%s-n
        case '-':
A|N1_AG$k0qkL              if(c=='+'||c=='-')v H f m%e'^E k
                 return '>';CV3K5xu$Ze
             else if(c=='*'||c=='/')_)It@J1m*pH{
                 return '<';
)e'\5V {$H9};T S              else if(c=='(')2G(?nPy?f7`
                 return '<';
5tQ%]7Ws              else if(c==')')3_ o2K Qu'ngm
                 return '>';
bJ9MLQ i%y              else
E?9l#VH$Z y6E@P,c4x                  return '>'; d`%e%b!B/`rh%A
        case '*':K0yE(vFTNAJ
        case '/':.~F Cn;xsG
             if(c=='+'||c=='-')
I{4i g5G                  return '>';
9e{(ki a?              else if(c=='*'||c=='/')
g?`&j9`8B1~[5U5G                  return '>';
g?q\@ZD              else if(c=='(')
#b6],R,z `;Rq                  return '<';oZ(R m4EVtA
             else if(c==')')D]X6OA?*WVL
                 return '>';2V{Z_R6T5^
             elseQew{lp pr%h
                 return '>';1Yf$Z.g%O| m!q5Q{
        case '(':
veFu9H'M              if(c=='+'||c=='-')b&{ fM;xB5Z
                 return '<';
9LV4@.^r              else if(c=='*'||c=='/')H'W-YOy@T0j
                 return '<'; Hym.fE7s
             else if(c=='(')U{7@G XAwc'o3I
                 return '<';
F&V ]a%M5T              else if(c==')')
a^Hxj4v'|w                  return '=';
/C^S/qbb:K;?v q U              else
!U8^2{z R u \2f                  return 'E';
R:y#tb{.uV1u)~(`         case ')':h$[k"q[O#K2n2J
             if(c=='+'||c=='-')*E$w,z/lh)RI
                 return '>';
R$O0S_[Ke N              else if(c=='*'||c=='/')
2a+JR]]Nw6b                  return '>';
n.S6sH~e{!T9WE              else if(c=='(')
Z DI Qb^ E                  return 'E';L*~&BO/QO&y
             else if(c==')')
jG-_\A5e)h,l                  return '>';
p+cm"xD&_ P5_              else
k)P*j+TM*nF1k                  return '>';
J+j9[Rj7m         case '#': rc8_]!r\z:M` l]X
             if(c=='+'||c=='-')}n] U)tn|a
                 return '<';
eZj[Zy|4r0^1C~ c              else if(c=='*'||c=='/')
7?gzC:I3oR5_                  return '<';
&e6d!w0wP A.j              else if(c=='(')
$wn K;y#eqk"E+n                  return '<';
oD6?JGGa$If[ `              else if(c==')')l.NM NM8E
                 return 'E';
-pb:p"Kk*Q              else
IA _6Wq9ZRt9t                  return '=';a4m-C!V/{HP
        default: eb X%a/w u"r
             break; R.xZY%O1y
    }M"x| `_~3?cR`C
    return 0;    q_6} t1B3W9`
}1P)X_QV3cn
a9u R*D@3r*i\y
int isOpr(char c)
~x(d"|/J {WXtHX A0R
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
+_cN [8H%n(D i}         return 0;
x+x$v1V(q     else *b/^+n|&y7V
        return 1;3J Nr5f NF
}3n4[K S2]o(o,t
!H,s7XP'ZF)N4b
float operate(float x, char opr, float y)
T(YM9\ F m m x5V {"y1[ A Z x ^e.D"} e
    float result;,n8tVp'G+d
    switch (opr)
5|%A IA5xu3A'~     {3~Pt$_jLm
        case '+':
!mb;y!O@ y"u-JW w              result = x + y;z:qF9~#F9T7^Vx'Y
             break;7i zj c"l:o6k+C.a
        case '-':
)XC`|p ko7Y              result = x - y;;vE z(M)vX
             break;
v4rj;{5z;UE%h*II         case '*':
,r#D Jm3g"D7Ew@              result = x * y;
(e ?GTS}A A              break;;_4jqU-I*od']5?
        case '/':
:~i | ZmZ              if (y == 0)
Vx \Fu-S9Z#Cb(n              {rzP%P|`"e
                printf("Divided by zero!\n"); ~Kg1U y
                return 0;
(Z4F:I-f}7K              }j K)V jw N
             else
5CnX:z-g'vO&M5x t6G              {2E#kN6m9K
                 result = x / y;;M(E,b3\At {1U
                 break;
2Mw*lLP              }
Gwp&?W        default:
\%v8u5n;f              printf("Bad Input.\n");
i J"f zLoZZ              return 0;
f Z6R3k[ Of?     }
WikmE7G{9T1X     return result;
2jpu-P`~zf ~ }   
)Op_K Z
-S aL_eNH[+v float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
/TY1I)~"] {v dg x\i,Sr;|
    Stack optr,opnd;
*yx"h)B5{U.c     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
_ Y&d-VL&qn)N1_     char c;
7GeO\$f^3anhz     char buf[16];
|.C@ j[,Ej{+bX     int i=0;
.{ O9hVqk*P    
;lC ~^@Y     InitStack(optr); /*用于寄存运算符*/
DxTo.U8s's!B     InitStack(opnd); /*用于寄存操作数和计算结果*/
o*x8k*Hs(t     memset(buf,0,sizeof(buf));
4rnn N4o+g&k    
A.c4Y1k!`i0Z AhC     printf("Enter your expression:");.lW\7^|9p-@
        
r4Qqm6lT1MC'H     opr_in.ch='#';,na,n-_vIAJ-jt
    Push(optr,opr_in); /*'#'入栈*/Jh0B P0NX)f+^Z
    GetTop(optr,opr_top);L-l7m#?"N-^ d5m
    c=getchar();b:As0@5`OX
    while(c!='='||opr_top.ch!='#')(d JuRg6a e I X+q/|
    {_8n%F KzW
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
d/\4`J_*mA         {%Js/L:L?!p+ob I
            buf[i]=c;
'uQg)F3XbI3?z             i++;FJ;c(Pq o7|
            c=getchar();%L7l/l;rp!^
        }
gun9b%@#i:_         else /*是运算符*/
8C'sZrw         {+Wf.xB"D:E
            buf[i]='\0';
ape%Kh_6h(`             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ W@'t9B#f:tA$q(g
            {
V|*n&H)xfh.B&JD                  opn_in.data=(float)atof(buf);
/KNs3z^!yF                  Push(opnd,opn_in);&b5]u%t B*}
                 printf("opnd入栈:[%f]\n",opn_in.data);
f w0u(?/k N9k8t l5Z                  i=0;@2wRZ {9`]R}/Jq/M
                 memset(buf,0,sizeof(buf));
;LCzf9iCl|D             }
2t\:x T%yY9@             opr_in.ch=c;^+b1L+^ Ia
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/.oc[ x J2]L
            {
m#~_ @/tNk1x(g                 case '<': /*优先级小于栈顶结点,则运算符入栈*/
(uZ @T]){$U#K"C!~                      Push(optr,opr_in);
z-Y(TN`~7kD                      printf("optr入栈:[%c]\n",opr_in.ch);
o gOMt/x;jF                      c=getchar();R#zv6R-O*\:[,e
                     break;
B7R~)@,];F!|6^                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/J+WX:iPn
                     Pop(optr,e);~Q@yJ+n.N
                     printf("optr出栈:去掉括号\n");
xS,{D%n,Z.[*oBJ/X                      c=getchar();
Q)n/};w5Oy2@                      break;y4g7Z5\e
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/&\ z4xw z#\-GF }ci
                     Pop(optr,opr_t);
ybA:fo2\k ls                      printf("optr出栈:[%c]\n",opr_t.ch);
]J~/E i*^8z(L!M                      if(Pop(opnd,b)<0)P[ @~kDju-Mc
                     {K$Nfh#Q9]^
                         printf("Bad Input!\n"); yq n gJ7i]
                         fflush(stdin);
Ep~p)z G ]H1U                          return -1;1u3Of*JJ#pR j"vv
                     }
w%VN2]#F%A@"cMV                      printf("opnd出栈:[%f]\n",b.data);4WNBI%e IH
                     if(Pop(opnd,a)<0)V*d_"Y.@m-}%D
                     {&P6t3M8_l8B[
                         printf("Bad Input!\n");
7J[ J!v]%Gb2Uj)F                          fflush(stdin);
,]v8SU.owo                          return -1;
R t*~ kH                      }
5m{*skv:L                      printf("opnd出栈:[%f]\n",a.data);
vu2@(^C;S                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/CA/vvZd
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
1}+B-co#Q lO                      printf("结果入栈:[%f]\n",opn_tmp.data);w|N-?&n k
                     break;qh#N O(WM^ea|
            }
'{-M,Gh"B m&S         } Btkr3y0ew
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                i9eG ijyB
    }
7]sTG4cU$x     GetTop(opnd,opn_tmp);%ty K"hH~C
    DestroyStack(optr);~]/x$DL2c
    DestroyStack(opnd); Q/s1|S Z
    return opn_tmp.data;A!{7g5j)M TG }2~
}
G3RX!r-i$mH$u QL.YC~
char *killzero(char *res,float result)
wA.R.bz {4vy*s'XAR{
    int i;5_"C[3xk c(U
3V0C)K(S4sA4u7S
    sprintf(res,"%f",result);g#J1H[-U*L {5g;`
    i=(int)strlen(res)-1;
&u1Lz_Hd     while(i&&res[i]=='0')9cc:Wwx+C
    {5R*EQ2Z/PO;WK,pm
        res[i]='\0';
X#qgE W.z&R         i--;6\i.n;on
    }
OgN)RC RB     if(res[i]=='.')
V@8lxg7c x o@         res[i]='\0';
*O,W;d-gp}W1~S     return res; W5ADSFV
}~bjZ&d9K)r
5^tjp})i6T D:@@w
int main()
n0w8L~Pw {
/y |'X2I L?:}$E8x`     char ch;
I m8beK5G [Gl     char res[64];b Bv Na&ZzLa!p
    float result;
/@:`d'j4AE     while(1)-d,d:z%|A
    {Nk_Z|9ZT(B
        result=compute();'eoY'`3V(o!B
        printf("\nThe result is:%s\n",killzero(res,result));
$@ _Z1{.L8N8h#o         printf("Do you want to continue(y/n)?:") ;;S-T7lCQ-L/D
        ch=getch();cYFeT#s!qX
        putchar(ch);
9e+c4a8` _4}O         if(ch=='n'||ch=='N')$Uh e)dHYK7Oq
            break;/pj;ZP1x}1Z
        else
,XhO'ALe!b8x4?i             system("cls");p P5z$^ },W
    } p;S8d2M|
    return 0;
O+Z.p#x.}CV S }[/i][/i][/i][/i][/i][/i]
2[:uD(`j&l_
!}2j? ~ X6F+L(j*| [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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