捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
x_I? E 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
S$Md%|Wn /**************表达式计算器************/
u,^w ~8|w #include <stdio.h>&\F E9Y:[+q%nG)P
#include <stdlib.h>
x0@S S D}_ #include <string.h>(f1Ua:ha
#include <conio.h>
(d*rc {P v W #include <malloc.h>#k;laby8M{'j!L

$Ze5O3d-_m3\/G@ #define STACK_SIZE 100
h8v6ff0M)M(d #define APPEND_SIZE 10
dg2f"M X9p
J(Px$gRc struct SNode{ x5j(c)DjCo
    float data; /*存放操作数或者计算结果*/"{!@2n0u,k'bbA$K8c5o
    char ch; /*存放运算符*/
x}/N;m!uh0A };(K#Jx2X1f
j5U1b2M9`(Lbq|
struct Stack{
?'O+z2O"`1S/Cf[     SNode *top;-hI8^d^r7w#JV+}
    SNode *base;
"]S3WVX@u     int size;
,w6T#b1h2M9W };
e0F:Kk;~` Ho o.gpPT}i
/*栈操作函数*/
Qa~M0t\Bv$@ R int InitStack(Stack &S); /*创建栈*/
2B6yq2P0F int DestroyStack(Stack &S); /*销毁栈*/8U#P6_/E;Zz8J&M9i
int ClearStack(Stack &S); /*清空栈*/
c,Hk,m)y7TZ0Z:j1t.d int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
(UG(s,V*C K:f1K:J!k int Push(Stack &S,SNode e); /*将结点e压入栈*/
!yk0\9n"k^ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/`:Eq&q P6F [(?
.n{6FD Xi,g'gn
/*表达式计算器相关函数*/*xtb x(G8}n?
char get_precede(char s,char c); /*判断运算符s和c的优先级*/5i(PE)ld'Bxg
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
9EY X1tq9x0O0\*AA+G float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/0W4B,C"\~$}6w0M
float compute(); /*表达式结算器主函数*/1h2k%|bUN/y8qB;S"_
char *killzero(float result); /*去掉结果后面的0*/
s.a-l e'bNR L`4Ws_m+GoO
int InitStack(Stack &S)C5d TL$p
{
)^ yoX,LH9l     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));b;H4`/c| _
    if(S.base==NULL)
u#Gx9k-r     {
@`zbFyO"_         printf("动态分配内存失败!");
:t:?(_d+JJ^'SI         return -1;[H6x/@2uH
    }
#Oc\y(YnV2YA9EL     S.top=S.base;
|At av     S.size=STACK_SIZE;
JYl+?z2YWqa     return 0;
E!p dY\2{N Fw9r#S }{o \D z1]j B
1_9q yo!^(D!_
int DestroyStack(Stack &S)
.}#`k*e6T {^fx/gY qz
    free(S.base);
-Eq&MJ8z'N     return 0;
+N"STH pA }
W:L&LIz(y:Q $p.Q#h ?+mV
int ClearStack(Stack &S)
e}|p;X~ {
G a5zrq? W-m,M     S.top=S.base;
^)ZY#\F/T c7VO9g     return 0;
[W(}UG }
j8V-?1~7~0e
NT(]\;U-c$wE z int GetTop(Stack S,SNode &e)
P,HF9o]D;U$X0Qrc {
/T8f NrM(w$O0p^     if(S.top==S.base) mM Fwt/W1h'g)@
    {
0z [?.wc{/U$W&{         printf("栈以为空!");
%]w7qEkb(t1},h4?3^         return -1;
rl9g.~VUn RuA     }
-pZL(TP3ny%a     e=*(S.top-1);'G MF1cC]%V:`
    return 0;
0P2au|HE$Q o }c[*X;T3qQ{H}w

\-C4Hrc R1H int Push(Stack &S,SNode e)3Dxq~8k
{
;[ K.p/\ H1xb     if(S.top-S.base>=S.size)oF#DByc/s
    {
9K,V]O\o+k         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
j%W5BcTP*x*]/}l         if(S.base==NULL)
.lX?(E x6L         {
qw;m EI)E0uW3`             printf("动态分配内存失败!");
-|Q9~~3LV             return -1;
[)e2y"[9V%M         }
6M p V7R5Ms2x         S.top=S.base+S.size;
$~)q:B*ftQG.nN         S.size+=APPEND_SIZE;i~)m7M1AE8a
    }:XTw s2\
    *S.top=e;
k;Pi0Eh|vc     S.top++;,yo,^Ck;D
    return 0;
$D%lc r)g3j6rP }
KQ`&\/^6| )Ey0|9]!N)zO9f-j
int Pop(Stack &S,SNode &e)/oKT3I0L3~\
{fN#[Lr%G#N
    if(S.top==S.base)|4{%_;oRuL#@
    {
eBv F%L6A5r/?@,cQ         printf("栈为空!"); q%X|3|3W;^S:S(W:D
        return -1;
X)N3M#^YZ$Xb f2E9Bj     }!Y:~II:W7BPy
    e=*(S.top-1);h-V/sr8r%o s0^{ J
    S.top--;
&{ CI uxW7tzs     return 0;
6q!f][&N T|E }1_q*o"H;@:sr8E"U

:b,Z!a E o!\S char get_precede(char s,char c)
hBb#DI qy {
.w&C,|rv`9C+Ec8^     switch(s)
_S(?#nwqM_ u     {X\ b ^Y$nQf y
        case '+':                 
&Pij5Wml.?"`.Z         case '-'::Y-eM5X%E
             if(c=='+'||c=='-')
$e8i(u.[*{#}u6\-b                  return '>';
F8N#^q-jQ              else if(c=='*'||c=='/')
$Za |'F{9c8l ~6w                  return '<';Onl l$j
             else if(c=='(')
%fN?^+Nc)Zqw,]                  return '<';5[a \!jL8p
             else if(c==')')
"q'j q9Nb#Z9ZBu                  return '>';wzjt+ri4x
             else 0E*WN8Xc j
                 return '>';2vv Y4_f'\6T
        case '*':
r]{9k0l5s9V         case '/':
K t @0jo:J YDV;q              if(c=='+'||c=='-')
"y2B8n9p%l:eKG                  return '>';qwIs Fe"{ A
             else if(c=='*'||c=='/')s ]sp9g1]%G
                 return '>';jBR`3`bko
             else if(c=='(')$w#J9L-z ^ia
                 return '<';
6p1aiO6{i1}4`J              else if(c==')')
v!Fe'ns#ut                  return '>';
5ye(QV,@ yQ5b%{              else%K p4W9Ja%hhC
                 return '>';
\4q5Rc'^/j-R         case '(':
H n"h6x(g]g e              if(c=='+'||c=='-')
iyJ*M*ws^G                  return '<';(xz h2sQ fa5o
             else if(c=='*'||c=='/')^ [W,j+I4Qsu5a
                 return '<';$^1vJ[ @a$m1L x2l[
             else if(c=='(');i QJF ^A(Vf8e
                 return '<';9lf6t-X,XU/~ T|W.|E
             else if(c==')')
G^"@t:Bl0V                  return '=';
:E%f~t"My l#M              else
;Z$F){+@d,M5q8p                  return 'E';
h,nWLX+^)j         case ')':
QC.c5lG6y7r              if(c=='+'||c=='-')3~jL$QX c~7?
                 return '>';
d5R1I&|k)b)?              else if(c=='*'||c=='/')f9X|2aZ
                 return '>';
vb|8U&@              else if(c=='(')
5[)yh4IB:eh                  return 'E';
Y So%w oFmi+b              else if(c==')')
*YQ K PyBy                  return '>';
j!g:k}*l#l&J%iN              else_`rbc,i
                 return '>';u"w)U1VZX2a/C
        case '#':.QN4{ Y4m
             if(c=='+'||c=='-')
4F(}G5r#v h                  return '<';EjoZUZ m
             else if(c=='*'||c=='/')$Jyq pZ
                 return '<'; NUB.L~8W"Lm
             else if(c=='(')nS:y3v-D6Y w rt+u
                 return '<';'X4r7?8L8wp
             else if(c==')')(~8`N \'~*qW
                 return 'E';QZ]r6wD#w g1jWW
             else1R5r x1e7[_tI
                 return '=';+l&Y N.nP:q-DM1mC-_
        default:
;Z#vU VUuqxxu              break;:Rk]#a0IE @ AkwK6}
    }
6L5Z(|'Oz#r/@     return 0;   
mv8B P HA }
3] U4Z,Qr*G0GOh\
2P;_Y g Rj int isOpr(char c)*?8|+D(s]dv{
{
y.Pk4|7rbCS zF     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
2n7Q8}?w6eGN         return 0; otY"l8LkM E3D
    else
\.sb"h+D~6f.lc         return 1; \3`)c8jf d%x
}5p5mhH)u8} R

6OL;A G6Q\b9L,l!d"a float operate(float x, char opr, float y)X{\KZ|/v8^nH
{
iFe j+x(\`     float result;
2Iti!CZy|G)t     switch (opr) B2rz0p4U5v[ G
    {$~x0D2EPx
        case '+':
'r-T |7V.VC              result = x + y;+a7h(Ow0]6{8]J
             break;5O:[ f${g6z\
        case '-': +VfpY.v Y~7V9W
             result = x - y;M!C9C-F eJ~G
             break;
? X R1|3h5U         case '*': WP2@7UvT q
             result = x * y;rx4N8eNb
             break;
~"iJF#` D Z         case '/': |'E0SOG q
             if (y == 0)
nH&T*y W!Y8~              {
P7u ] s)d)J3^&L?                 printf("Divided by zero!\n");
jQsE9}a d3g                 return 0;7{*[uS)\9e5Y L2_C
             }td|8A4b(?@6^Q
             elsecbD#fn ? n!]2M
             {
%V3v{k R                  result = x / y;
XJP Z2YUt$rMxY                  break;
hz,[d!m2x!v'i`              }g:T/Fa] ux
       default: ['^NXI)c~l!m G
             printf("Bad Input.\n"); YM-rN&f2C.QL
             return 0;
^^ ^.|zTc     }
fX*rKV%l4U |     return result;
*?$FZ;I!p;Rt6Ti5^l }   
2AYl0wZ
&R9]WYqQykU float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/5\0t-W a e5lP Gva
{
-}S%z0Z2Vt     Stack optr,opnd;
7t1^s;bmbyF%d     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;|;R:q-z(k$sR|
    char c;)cLXRy.Qn1R5HP V
    char buf[16];
6K]#Z0?-S%k     int i=0;
:^~u8q p%x9r    
&mZ,i&DD[ z0fG     InitStack(optr); /*用于寄存运算符*/P2r#f:El5?%J4p
    InitStack(opnd); /*用于寄存操作数和计算结果*/
dWlZ9tB ? B$]&f     memset(buf,0,sizeof(buf));"\uc'v*o;e;P a*JW
   
U(L d h3J w-g     printf("Enter your expression:");
_ S-sN#JB)T o)x.N         
;sK_!Sk|vR     opr_in.ch='#';
{?SD Q     Push(optr,opr_in); /*'#'入栈*/ `[6uJ6@H3v q VR
    GetTop(optr,opr_top);
U}5l&] KC/BM1u b;q     c=getchar();
si"\0w YF d*P-|XpS     while(c!='='||opr_top.ch!='#')4Ha2l9p S#[9`.H$`cy:[
    {*p;L4xP+L aeFl C;W d
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/(@H1z Y3{ p%kt1r
        {
;@h0f6U'\rr ~             buf[i]=c;
vgC YjyK             i++;)C @D;N/Pw6fl VV,s
            c=getchar();
F'D6kh#a7c:_$B)y6{         }agI(bh l
        else /*是运算符*/
Eb3^4X8u0ECv+`7D3B         {
:Q'c%]T:[9^f3P             buf[i]='\0';
q2{;K;q BTn             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/;g8_:M'] z
            {3H$`(M,Bi;x+FE
                 opn_in.data=(float)atof(buf);
sR#Enqe$hI                  Push(opnd,opn_in);
&W&mq7d@ MX-Y                  printf("opnd入栈:[%f]\n",opn_in.data);0}JM:@+~~
                 i=0;
7}{sy&p:wDi]xF GR                  memset(buf,0,sizeof(buf));5A%T;]0Ng
            }
h a`6p3J/OH2s0w             opr_in.ch=c;X4{u7b&lJ ASj
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
%k"aDL)lh5v             {
y]-H4M:W                 case '<': /*优先级小于栈顶结点,则运算符入栈*/6Y4t7?2S6|9r%o5V1sT~
                     Push(optr,opr_in);
!Z*}a(R T4M                      printf("optr入栈:[%c]\n",opr_in.ch);
}'[2H%s{+y#I                      c=getchar();
N.?]I4vo/Q$S"a                      break;
we%tVQ3Q]                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ D)uV$a.yS#ya
                     Pop(optr,e);
2z w"J |"B/Ni                      printf("optr出栈:去掉括号\n"); foW`2Iq1j XG
                     c=getchar();
PR1j@:u)H                      break;
3v k Au5M*zUn                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/#`-[h?'S)Bc#c
                     Pop(optr,opr_t);
6l7G7Z(s3@t0u*B                      printf("optr出栈:[%c]\n",opr_t.ch);9n Us"bqO
                     if(Pop(opnd,b)<0)
6\nx'`@8\                      {
*]Q {Ib#X                          printf("Bad Input!\n");
t C#`)I7m                          fflush(stdin);_7zJhk+g1`]o
                         return -1;
J m"_6{%e%\ f                      }
;Y_@nb*u                      printf("opnd出栈:[%f]\n",b.data);
X*k1QD@0gWM                      if(Pop(opnd,a)<0)`%f$b!sOl/m I
                     {
u7Z"m&Y`P.U                          printf("Bad Input!\n");
e(@"g ]$\A,i                          fflush(stdin);0Q7I,\8d)wW5A)[
                         return -1;*mD+gj9ovu!N
                     } U!A y|8i d$js l
                     printf("opnd出栈:[%f]\n",a.data);0t c4pK8l+Q
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/.pz-}5`4Lz
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
!tPr5dpF@`Q                      printf("结果入栈:[%f]\n",opn_tmp.data);;k,MKb^mH
                     break;
$QD:g @2s(zs1G:M             }/}m1ZKA.j)tQ3{f
        }}2]rrQ`:N9C
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                $Sw"\&g6IMs(c
    }
jD;W)O^TuG8Vq     GetTop(opnd,opn_tmp);'f"A0o6t[8S Q,Y
    DestroyStack(optr);
1^)o[z'mz:j'z6B     DestroyStack(opnd);
K EY4WF?     return opn_tmp.data;
)~9W4h/\4R }xv F5W!vS4S

2p Sg7rce char *killzero(char *res,float result)
D1eGZU4r[;H {w^"U@-@ R*^c,k
    int i; wfq X0ycF
8oez sV7W8|0us
    sprintf(res,"%f",result);
6q'@x(kI)T:q     i=(int)strlen(res)-1;
ZQ*LO3F2tk:`Y9o     while(i&&res[i]=='0'):V VQ.puHc
    {&m0V [!v@X ZQ v F
        res[i]='\0';
hDi/oE8O         i--;
6Rnk;E Y'av T     }
8TF-s I plH     if(res[i]=='.')N^Z,{ j'm
        res[i]='\0';
3SlS"L_ \|9w     return res;&Z!o Df l0y,BY
}
![Ioy@$e 2^ WZ+t7dL5o
int main() c*`&E(Hf!T
{,yQp7y;jb9B
    char ch; ^0v)g f^Q
    char res[64];9KAK;M!Fz
    float result;
/hV{F9gz*o     while(1)
a(aZoD     { Tv7? Rbvs
        result=compute();xnDk-W'w
        printf("\nThe result is:%s\n",killzero(res,result));
.Y^U&_8S%r         printf("Do you want to continue(y/n)?:") ;1zH{ fBbmZPzP
        ch=getch();
bP%hX I1YH5FUd         putchar(ch);z;~0AY*Ue
        if(ch=='n'||ch=='N')
z5be g;Mmzi+N"ko;Y             break;m(C `enH&]"[
        else LcI7rPE6xH)r0H
            system("cls");f7I)\.g1Mq!h ^
    })mZ&i iS.hB9}9yA
    return 0;-|K%k1H9Q*i9Ib r
}[/i][/i][/i][/i][/i][/i]
ay6X |:jWP
9pTEy-Cv [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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