捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
Yz$l `3H^ 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
|0t8u$kx&Z P1Lf9n /**************表达式计算器************/
C_8oF7m ?,JZ+EjW #include <stdio.h>
:W#Ree6j.c3j #include <stdlib.h>hQ!S q)o
#include <string.h>y*b.K Cq v
#include <conio.h> j"s,]lA~$ti~W8kQ
#include <malloc.h>
+u.fT8g+{h-MQ +M4l"OJ1y7[7y
#define STACK_SIZE 100)M7dA$q!kk7^
#define APPEND_SIZE 10
W Ljo3XME 9o5{Y Qg].O7x
struct SNode{]X9_[OX
    float data; /*存放操作数或者计算结果*/+{h5qSt X
    char ch; /*存放运算符*/
A K{6X&f?? };
!puQ)N v,A h"eJ L4g @
struct Stack{6\+g|/O5US
    SNode *top;
Z!R#B _;M"X     SNode *base;O u||P y@Htu*Nb4w0{
    int size;gX-z-? }_ N M1^6_
};
c,VU ~NX9c
ImXKG K /*栈操作函数*/|r c(`9He*yS
int InitStack(Stack &S); /*创建栈*/JkXF k1\ Ak/X|
int DestroyStack(Stack &S); /*销毁栈*/Gbz/Hny*f&A
int ClearStack(Stack &S); /*清空栈*/
CF w8E:}/FEu int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
&Q gQ`*S,t-M!p int Push(Stack &S,SNode e); /*将结点e压入栈*/
q1J!x"V7w'R int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/kIM'YAo7j7R
vt8tZw/@x
/*表达式计算器相关函数*/LE?m'[]
char get_precede(char s,char c); /*判断运算符s和c的优先级*/4h}S%y V9[/Y
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
~5Hk,S2t float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/3RrGEZ7t(tv:_
float compute(); /*表达式结算器主函数*/ t:Rt iSwJE,]
char *killzero(float result); /*去掉结果后面的0*/
0O4Dc;Bs~LU
/y+UO godv int InitStack(Stack &S)]?1K8]~ Jr
{~&@4H&O4RD
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
d1_MpwBf     if(S.base==NULL)
/BI h v~cbZk     {'p@5C+i)Z'p
        printf("动态分配内存失败!");
2c oB#QIC r         return -1;iu[8g9EH.b
    }7Q;rJ j!h2RC)U:K*v2F
    S.top=S.base;
Oj^A"Ac%G:j     S.size=STACK_SIZE;
7z%m I'x%T0fT_4n     return 0;#Q DvS}6} BZH*y
} J&a`Y-@ Us)]9|

%tew3l4n"kBn%Z int DestroyStack(Stack &S)
]4Zxbv5lBe-HG o {
&J#F[$H ~`&d+X     free(S.base);x c_? H2J
    return 0;
e!e7?9v-k+k`6lJ:{ };{;v/d2V'f hp3?M
8TfY%aS6|T
int ClearStack(Stack &S) I*a8oPb9|tX
{r$q&l`4C En W4}&pM
    S.top=S.base;M?[H*` }6P7V9J8` D
    return 0;
%EDOfy#VF,l }
Wf_#N2Ae"g
/l"G2tJC ? int GetTop(Stack S,SNode &e)
+k.P!z f(Zx#Y {
.MBj|Im-F+b     if(S.top==S.base)
l)i$|1m4Yz D     {$[iO~ y5YZ6D6U3q
        printf("栈以为空!");
N"O})zBM e         return -1;
#u b.J?/Oh     }
"u ['We4ln     e=*(S.top-1);,^pyEM${:u9O$N(x
    return 0;I |O:n sI!M
}+?W-n*oNQ(S|

5N!o"g!R@?&G:y-QV int Push(Stack &S,SNode e)wVO#K%qO-p ~B1A
{
lz%A'C+~!{iR     if(S.top-S.base>=S.size)
$j,`,Of?'dLX.d     {
"n"D/\ aCY3M         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));v3{ L P.|z
        if(S.base==NULL)zZ}5W*\r
        {
6k,u$J%F5~7qf             printf("动态分配内存失败!");
5[Lau y!l2F             return -1;f^X T6IX:U!T
        }
XARGb-D:Q F         S.top=S.base+S.size;_LF:tOjZL
        S.size+=APPEND_SIZE;La#W_u'i+Hw9K1PS
    }M};Wh|5C7L8B~m
    *S.top=e;
+j6L*['T$`}     S.top++;
Ir J(JaeD     return 0;^g7G@v&s1}t
}`b!i H9_/t

"s b)WS0DRT!M"{ int Pop(Stack &S,SNode &e)
!du:E G;tB8TOF {
jJYTJ0Lu};X     if(S.top==S.base)
&f*^*wgS8E}     {L2mw V^U,R
        printf("栈为空!");
5To n_OU$y2N         return -1;
g7@ t ro"M,\-j2v3r     }
U,rx4r[.v`$Uu     e=*(S.top-1);
E5~D-TU8j+}BD     S.top--;
Y1P7tk rxF6L-]([     return 0;
sU!W/e2dd5Yr }l6Y:e uc#P"A/h1olr
:C:jZi"})LO6@\1T
char get_precede(char s,char c)5ZqP#D;T"v
{Z1F^Hm
    switch(s)
T.p)l+yU     {eH7rITe
        case '+':                 
}dY@ W,` bU         case '-':
WY NK$p PQ              if(c=='+'||c=='-')D a Dy9u
                 return '>';cY NGZ
             else if(c=='*'||c=='/')
&o0n C.F&g%q0w{                  return '<';
z,d(s }'Q)H8kCn_              else if(c=='(')
E[v+v3w;\ r w:vS                  return '<';bIG"g9AVW4J T
             else if(c==')')
(c e9k.~d'} x)We(\                  return '>';/^`\&ze$u)tD)t1UG
             else
[Fb7R j}8WwwO                  return '>';9Y,j%F!~?1_
        case '*':
W7JJ@9H k5` ].Q         case '/':
eA"v'BQ4D_g*w              if(c=='+'||c=='-')
0nIezs                  return '>';
cs2B@ ?,Y-Ac              else if(c=='*'||c=='/')
0mH"q2n[J,_                  return '>';
RKE+_n S Vpq1iN              else if(c=='(')&nBv xV ?4H
                 return '<';
v/cYn(x#l,_}              else if(c==')')f4G$SW5q/X6unb3]
                 return '>';
9suJ h;N8BL$v              else
6Us{(wy8m ?A                  return '>';
5a)m)^e)U4X         case '(':
k$s6{"J YT UX              if(c=='+'||c=='-')
!`lRC3T                  return '<';4orO6s'q*u#iO
             else if(c=='*'||c=='/')
,@5HS l6rKW                  return '<';lKQv}_3v1Vtf
             else if(c=='(')h u9lZ1|t\
                 return '<';
+` d sVoYw,Y0f              else if(c==')') ^ hf$FV6\FJ
                 return '=';
j&biE Q@5p"w5~              elsevW@Fb5RzA:Y
                 return 'E';
j2K1R.lz^]BM         case ')':.Z[{0v#w3K}%G5t5w
             if(c=='+'||c=='-')zxEDcs.z*L(?e
                 return '>';;~#nDUC/~&A;Yq?%Q
             else if(c=='*'||c=='/')
Q+o us-EA                  return '>';6s-tqDup'b#C|5Q {
             else if(c=='(')rr:`!^Du }AT o
                 return 'E';H7M1KE9ew0Tl
             else if(c==')')VhYJ\Do w&UY~!l
                 return '>';pc/w2V%Sc*aJ
             elseU;rO,Whck8PG
                 return '>';
G7E iE s         case '#':rT5} x)C$I,R@
             if(c=='+'||c=='-')Z}N"Oi F.w0g_a)u1i
                 return '<';'b4cA n"r0o
             else if(c=='*'||c=='/')
g|'E|sV&fp                  return '<';FGE+`+|6b;V
             else if(c=='(')| N Ub]!wy#@1J
                 return '<';qdg!zwL8~{
             else if(c==')'))Kx hq%RY Q~
                 return 'E';JQY/]3C6[7cQ S
             elseDU y;l-QiT
                 return '=';
Z3C:U"v1jP,U         default:
:s GV$}7P              break;?W#|)tS
    }
XB0Dy+b     return 0;    "a8gY[p3gmh'I
} hL'c(g6DM"OPyl8E
%_#CZh9W4a
int isOpr(char c)
vT7^c Y {
Fs9A(?&Ey~L`/h     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
k H0@A!CW_u         return 0; {E ?Dj m)Bg
    else \8`~'YazUTR&Eb3}
        return 1;s-q{$Av%I
}
9fm0JW Z3{q `"GM
[~.iBkz}!u:A:F float operate(float x, char opr, float y)fH4Hu"`pu1Y
{?I L%z SNOT
    float result;aK*?G4f-o
    switch (opr){+v"X%a(w*k
    {O8}D n)KVY
        case '+':
%X'V"K:u9f&H'R              result = x + y;
PE4OvEYXk(^X              break;
q:] ?_d,k(g         case '-': /Q!@j9j4fyFr
             result = x - y;|3x#U.]t6l}:M!o
             break;
q:v7z5f!K.W;C7A'ts         case '*':
u kjU!w%e              result = x * y;v(^r1f0nIH'g
             break;$N JP9eTHn#bz
        case '/':
^H7B;s:i%iP*G#a S              if (y == 0)
5s:`&t#FE+v              {
B(sk+S'ne.As                 printf("Divided by zero!\n");
!s9blW]`~{}o"d                 return 0;
U1C1b\9Bp^              }
1?Q`,sYv g              else[x5W4qQ4Ib0Fp{
             {k l$}}mDq
                 result = x / y; CuI/z/f:KG
                 break;0sfP;l u{+CF7Z;B&j J
             }!B l:Qwe I
       default:
R6?(i{#z O%uw              printf("Bad Input.\n"); d |*Hg*zKHm
             return 0;!JA?fh{
    }
7b9ux M8g@ Fp     return result;pO2~ J \,\f
}   
toi7I[GO!j !oN-t&s} Xhu:W
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
Q4s z,XH { J"D5wVY
    Stack optr,opnd;
1TC#[-?5YR     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
*}-Nw*g,X:@dnG9l     char c;
l&u@VP     char buf[16];
X5O/D)D%E `     int i=0;"Q0Rp Z i
   
5EZ Pq:tcC     InitStack(optr); /*用于寄存运算符*/
1G2S-T}Y i#pt     InitStack(opnd); /*用于寄存操作数和计算结果*/xkG/yO^s9s
    memset(buf,0,sizeof(buf));
9~ _p6T*X3@A1Z?1[z    
{highM[-~5d'E1m     printf("Enter your expression:");
RR F;i9Dc$?s         
TN#@\m{D     opr_in.ch='#';])rAd:PCo [6`O
    Push(optr,opr_in); /*'#'入栈*/
,yS1S9v-n"T-e'b@     GetTop(optr,opr_top);
b0[1[3|,I7yR'?)s&w     c=getchar();*H@H:C.h mw;M"u
    while(c!='='||opr_top.ch!='#')DlQc:G_ONU
    {3e!A$l qj;L*m
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ @5ko8N#k0])v$l
        {l2]S#_%X
            buf[i]=c;{pW|&N(m;@W Y#O
            i++;
2fMZ-ggx#NT             c=getchar();rk/Q Y9\7X\e
        }
.V/y"V V:n ?U'e]         else /*是运算符*/ds|8F#RN ]])k
        {
@:Vfi7?             buf[i]='\0';
P.T:vhAM:qg:\NJJa             if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
wo${'v/{             {BtNU}I `V
                 opn_in.data=(float)atof(buf);u8_H/ZnkH-}#v-e
                 Push(opnd,opn_in);SvsOy2Pg
                 printf("opnd入栈:[%f]\n",opn_in.data);-xg*~8j!SDoSc
                 i=0;
!Fd W%Lq[                  memset(buf,0,sizeof(buf));
g4j4v8L!S jX             }
BpSt-_;_u%Y"pY             opr_in.ch=c;:? C9I6v%n
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/e?D G bw
            {y9`%Lr%nn
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
)Xx0?#S;r                      Push(optr,opr_in);
9K4c5?0?e{$y                      printf("optr入栈:[%c]\n",opr_in.ch);6k"LC#]/w4VS
                     c=getchar(); UH/FKrbR C
                     break;1R;D.fK~pP7W/M(^3f-L
                case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/)I ZN M8\'pM
                     Pop(optr,e);
I-s2kk3m4z3Y\                      printf("optr出栈:去掉括号\n");
X*NB8H&h m'W                      c=getchar();
iuN0e3Da3VX                      break;'k[:@;M;Xjl
                case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/5EA7T3u(D#L1L5Zqk
                     Pop(optr,opr_t);N!l(zV1[ ZS3l
                     printf("optr出栈:[%c]\n",opr_t.ch);
&W8eUhMe                      if(Pop(opnd,b)<0)
Ps`"F \Y;g S                      {
9eBy$Ya)Wq                          printf("Bad Input!\n");X3TQ$p-TV YU-c
                         fflush(stdin);
`/llfEY'c3o                          return -1;
R,F{0X+Y5eZ#Y8l                      }S2p'@.O;T$^`
                     printf("opnd出栈:[%f]\n",b.data);
/X)Z\Q*_                      if(Pop(opnd,a)<0)
u$_aZoj+}w"m                      {
OUrX`'wML                          printf("Bad Input!\n");}~E&zQ
                         fflush(stdin);
4ED4L.NH B)W                          return -1; g:P*E h|d+UJ
                     }
)[,p@iEz                      printf("opnd出栈:[%f]\n",a.data);
a`g$b? I+`                      opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/K6f ^k(v/M
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*//Fk:_bF[
                     printf("结果入栈:[%f]\n",opn_tmp.data);@6T8x:Fk0s
                     break;
vk}(l:x.`J*Ea             }
_2YYgZxj         }:f {(^n"i ~_2b
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
]3DVwnyHR     }G8cT!g?&E.B
    GetTop(opnd,opn_tmp);F}:?8Vm8W-H7R9w H
    DestroyStack(optr);r*p9g$^)@
    DestroyStack(opnd);
3B5s!p0f$L t     return opn_tmp.data;9v*pw(E~0q A(k
} c)m-k){3w
1Dl\*S1o)G(y
char *killzero(char *res,float result)#}d&DXoE3{#PM
{
C1O'h"j\{     int i;
T#l[GD3W
%ka|S[[n^     sprintf(res,"%f",result);
(h"v'U JM'B L1O-rv9^     i=(int)strlen(res)-1;%W*Jrs0gd
    while(i&&res[i]=='0') `$D4~d1h/gI
    {
g"[[U:MNQ|I         res[i]='\0';
!r9KI,Bg M)V!d3i         i--;"x$\#C9~'lX,|E8T
    }
b.W3P` jyg     if(res[i]=='.')
%R#H}E(D}d         res[i]='\0';
wZ-RKm"F'y3[o     return res;rES*O&[y
}
@Ar)iq B `PhV#_%h
int main()
(oazo&B$i)V9z {
(_Y{A%c*@ ZN     char ch;"V AnVV2u/xS
    char res[64];$\|I&{ aG?w:a'A
    float result;hZ!l`"h)\y A mC
    while(1)
jd:X-{3b]L6wS     {tA*vPj;C0@y{6j
        result=compute();
6e2G4GoOTV_.Xu-y9`         printf("\nThe result is:%s\n",killzero(res,result));
:FG,cA#{*K$T)vA'B|.u         printf("Do you want to continue(y/n)?:") ;
A4emA2x1e         ch=getch();r}4VQ$zR'zl)c
        putchar(ch);.Cr h$kt1DY
        if(ch=='n'||ch=='N'),h6jMI:?!U)}
            break;
J(mSILz.?])S/e         else
x8|0} V;u f-l             system("cls");
:U|KT'|!N;P     }
WF:rI*];h     return 0;YK{$pju
}[/i][/i][/i][/i][/i][/i]gcr+H3ok{
*S/X y Ftb O
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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