捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.A7L1wI.e"|
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
CPA @,l ^` /**************表达式计算器************//};NeHTM H4i/s7E
#include <stdio.h>?C6s:n F
#include <stdlib.h>'b/VS Zx-XTG+@
#include <string.h> i%f)a)Im F
#include <conio.h>
o:zm4\:aES%`]X(w #include <malloc.h>
]M Qc1f+Ho
vp6R OQ Qn&}] #define STACK_SIZE 100gq-S#zv4b8e`
#define APPEND_SIZE 10Z vE*cz0y
ca&J K;J2K g0e8SW
struct SNode{#F!RxC9`J6_
    float data; /*存放操作数或者计算结果*/0q/L`9R%]fp.[S
    char ch; /*存放运算符*/
QK@gt*D.z S };o ARMos
_Jq!ehC.@
struct Stack{
-s&vLBgW&D;j#ZM     SNode *top;m"GZ[E)F
    SNode *base;
g,w/Q Vm,Yi     int size;-P8F+c,w,j(ex'[7H
};]+wtVF!A

g"we3_4mLl /*栈操作函数*/8i'i3H]Xc
int InitStack(Stack &S); /*创建栈*/
~!n/w(C2}t int DestroyStack(Stack &S); /*销毁栈*/
)Lm0u/b?7J-t+KY int ClearStack(Stack &S); /*清空栈*/
QMq{Mu1@b int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
T'o fu\_8p^7z5\E int Push(Stack &S,SNode e); /*将结点e压入栈*/o5vw[T6rCB^
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/2bd:b9om
9v@m*k8n$F?;[
/*表达式计算器相关函数*/&I'Lv T8}Oz
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
?)}'z%D:X y._mz int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
/V W0Nb7m bj float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
D\/}\} R s float compute(); /*表达式结算器主函数*/2V6}_A&W1C;s,i
char *killzero(float result); /*去掉结果后面的0*/
,Aa~?;h-h |y`a8I
8p-J/Ri7W cbtW)H int InitStack(Stack &S)L'kfb&\f5xG
{0k1wvMj
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
!k.S%[G9G3h`     if(S.base==NULL)
v!a)Gi'NG1OzX     {c#m/`$kM{%x-MM
        printf("动态分配内存失败!");3Hi.N0Lh*OqB \D
        return -1; pr/SOdy^!R/r
    }
,Oq ?+Gl'{mo     S.top=S.base;
$hM(k5C P     S.size=STACK_SIZE; e/s"G#},Z G
    return 0;N"_Zxl!DX
}K` jK0n4U5V:ay;|;E
7v1L"mG7xl'h
int DestroyStack(Stack &S)#}X1}1Cxa
{
[+A,UJSt     free(S.base);JldD[8Q
    return 0;
l w+]#T&B+m1a }m(S-n.b$c4q{$k;m

FZ?[7M c int ClearStack(Stack &S)
u^-X'?iX4d:j v {&A&?;w"b8c]#V
    S.top=S.base;:z:_+C\5Mq
    return 0;
O V1L?``9da })CI+{Hk Gy~
]/xGHq3k/^y
int GetTop(Stack S,SNode &e)
bY{ \f-p {9J U:Hp{5ma
    if(S.top==S.base)(E Nc,T0lG Qv#X
    {
&[I~0x}`         printf("栈以为空!");%\o!@C6K3Z
        return -1;/pL`y2J Zb hq7B
    }B+n:C1W b%`2b%N
    e=*(S.top-1);B ` ~Q0JP)x
    return 0;
V:xk-a ~D k9S }1`(c"fTUR1P3?'WF
Yd^/_G%`
int Push(Stack &S,SNode e)Yg Ud7Xr
{
9S0j$Ial s,N,U     if(S.top-S.base>=S.size)
vXG^)F/?MV?     {7],q BC)~H,poc5n
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); @vk WtO-s W
        if(S.base==NULL)
&?+h|%b0L1sF/G         {uYF/?3zX1y&W"J:Q
            printf("动态分配内存失败!");,Y Sy;F2g:bwg&p
            return -1;%L#w.?)ai-Zu9u
        }({5qf`:Cf7e} gB
        S.top=S.base+S.size;
FTcz5@"Gl         S.size+=APPEND_SIZE;J2DI$l(S"c#]5K8l MML
    }Sl G:e+Ua%x m
    *S.top=e;thW;u/?*ohQ
    S.top++;
u'\8U ?:^5q9C     return 0;
I V^}~ }
F0d [7D/P%nV 1ad(P"~^*y
int Pop(Stack &S,SNode &e)7p2|VD[)b
{
4~&o$c3G-IAm K     if(S.top==S.base)
t e!?,n5]p1x     {
Hl3\0w7M         printf("栈为空!");
+g6DKbWu         return -1;xMA`%lq iA!l
    }
"s&P @X Avb     e=*(S.top-1);
U(T,d#bVz)o[     S.top--;o8K ZwK2wV @%R\&Z8GH
    return 0;
7n8P#z*pIT }8}/M:WnE

;E8X-DOq5\QD:r)u char get_precede(char s,char c)jfj!Xb V+S4i7B
{
S%U Jpwn     switch(s)
r6[SO5v     {/D ^+?7k0u:Ok
        case '+':                 g1C0{5J0^`d? u
        case '-'::C~WLE ~m
             if(c=='+'||c=='-')
6PS;[c'P Sa@J                  return '>';^F Y7o&\({ Wt-Av
             else if(c=='*'||c=='/')
)PoNW9G-h8z                  return '<';
e,iJ2O+C] _D              else if(c=='(')
l%D[K%{Ur5pa;R                  return '<';y.bE K#g~!n E X;K
             else if(c==')')
1I.L;hC_O                  return '>';
o,u&e NPL k              else
n^2v5{`P'y4PD                  return '>';
a'j'V3o&][q E)E         case '*':7RAWL%f9_1[D8W
        case '/':Vzc NDq5P7nR.gW
             if(c=='+'||c=='-') l"]9{S| z!n O
                 return '>';.Eh.Ag%Y$| In*j)Tf
             else if(c=='*'||c=='/')
.`V"I#e ]                  return '>';0f(C|)y\$|6I5V6k L
             else if(c=='('){ z$| t2oW
                 return '<';'xz.}@3l
             else if(c==')')
*]%Y/z0E[A g$c                  return '>';4Y?h'u({!`
             else El h${+M
                 return '>';
kb Qg f [         case '(': _0E3{7F s w4i
             if(c=='+'||c=='-')
S []wV:k PUI!x%g                  return '<';
No7P D['x5@Q7`              else if(c=='*'||c=='/')
1M0HG$}J'\B P(w                  return '<';
U&|3m$eJ|)r&A              else if(c=='(')
7_/?~&`!B;} w                  return '<';'I+z7@ X4X
             else if(c==')')+E;AS~gE
                 return '=';
7m~8A)GB oJ(R              else
j7]$zk"m,O@                  return 'E';C&K@h:p
        case ')':F T5J%jK
             if(c=='+'||c=='-')
3x`tgeq(s"aGS                  return '>';
Zb'W4H;r              else if(c=='*'||c=='/')
0tL$Z!f:V7sLeUo                  return '>';
o(s|wOu#?u!d              else if(c=='(')HhEcr*\2E9\ g
                 return 'E';
K!w/Vtec!`1u              else if(c==')')
Z_|O+tf%n yw                  return '>';Tg E,Ul;} G^b
             elseU mxG[d
                 return '>'; N"fQUjx
        case '#':
(rHwc6eq;L+a#X.P              if(c=='+'||c=='-')
j,L/W/XyE6?'\C)s                  return '<';
.D)W(o [ e.F,{|              else if(c=='*'||c=='/')R]$x1h g
                 return '<';
m&z[wc%xt              else if(c=='(')
a`j{;Y}                  return '<';;u.V3D:?B&@Z
             else if(c==')')
.X,D:GB'g^m                  return 'E';
|'IAX,[$e.?              else
rdBUX)Y0WFs                  return '=';
5_*T/g0J3jN9C*r         default:
'dmU%H*p j+Su              break;2z.t%o!r h"H p
    }UD@ q3R#O$?
    return 0;    .S,z0T5Y,`|W
}
.|'} zu)e8z2v(i;D 2U,PU3W)N
int isOpr(char c)b6}3Wrl,D4~ZE
{
L6Q$@e Q)x:z \ u     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')O4X3hh%G9c[
        return 0;1a@Y#[3n zK(RlS-j
    else kg"U2LW @%rZ
        return 1;
#~-K|gVrv }
$\P YP"S'j !C _a9F1N6M2z9Q9L.K
float operate(float x, char opr, float y)
w(Q ?)zZHg {
ln;ox6g7m,^_*P,z     float result;
5MNN!T%k#|.f     switch (opr)sN&w5Jq#j;t
    {{'J.X#s!D$e)\ko
        case '+':
GCCNjQZC\/X"_              result = x + y; ye9X4X m i$gR
             break;
$cydmb-?'@         case '-': Ut["| B`
             result = x - y;2L kc8M:`
             break;&O0Y#omo2R7G)QR
        case '*': shG-A}Z5y8^0|)?*o
             result = x * y;id}$XV%f)b
             break;y4Bi vx9Q z!M
        case '/': 6i;r2KQ"o&g
             if (y == 0)
M EYLx$v M6Q|              {2s8^ C-N]`I0C^8nY
                printf("Divided by zero!\n");
i)v0ISxB                 return 0;VZ&d"lE8R"R
             }x.{5w7~[/T
             else
avae E              {
/{@;r+h }6Y d                  result = x / y;6L;I%Fx!K%P D[m
                 break;
bX3UmX              }
4z;qF1U9^ ?        default: +xX u$E A
             printf("Bad Input.\n"); ?~7AgF l2}
             return 0;
9|+[6h&SM!\Yz     }
]`5QUyg H5J     return result;} QH T`5E }5x(k
}   
M_K.R \g c(mh"p.i6Gz7n9H
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
*G-__{Jit {
"Ec R$t~wA,[%t-@     Stack optr,opnd;
FDc2Z |T R q     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;!{6d0v"VW'ba
    char c;
d/NO.h*oOd(E     char buf[16];
"z%HQX-mc S     int i=0;
,F2w0d s_Ur    
&MA;j2A zyal*K     InitStack(optr); /*用于寄存运算符*/
e.iNS-D U3M     InitStack(opnd); /*用于寄存操作数和计算结果*/
0YA,vDCB(U'?Z     memset(buf,0,sizeof(buf));_g#v5T!a"v.k[
   
4@?(w8qr     printf("Enter your expression:");
O-{4jR+FI+L         
9`lP!I;MQ     opr_in.ch='#';!z2SG.nQAy5`(`
    Push(optr,opr_in); /*'#'入栈*/I8Qm6M.V'f
    GetTop(optr,opr_top);bG#YJwT2} K2?
    c=getchar();
)_2NOF {2` ]     while(c!='='||opr_top.ch!='#')Biyk!h.j0nF#Z
    {
Nggqt br         if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/WoTWK.c;Q2W K@ yp
        {U%`]B/y
            buf[i]=c;
7Ors2W,a}5`$@             i++;
Tx(Rv l5w             c=getchar();
(^O0J Vu         }
0yMsL#E*A*Uu         else /*是运算符*/kmzp!c F
        {%v$J? T~-kh6h7H
            buf[i]='\0';g)l5ox[5vZ5G
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/1Zz kM*mI x
            {
,S]Jl _/MYbz                  opn_in.data=(float)atof(buf);
4y+R }{ q(R\                  Push(opnd,opn_in);
2J].rQC w                  printf("opnd入栈:[%f]\n",opn_in.data);.H(mVZ C7K
                 i=0;B*}$@F!}nx%N_
                 memset(buf,0,sizeof(buf));
o2Q?r'@JM.N             }
&B\ ~R"w.fFS.fi             opr_in.ch=c;eI)}k _ Y^
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
9r }_7m;s(C             {
O7?K.lW4M                 case '<': /*优先级小于栈顶结点,则运算符入栈*/a$y U!M-MB
                     Push(optr,opr_in);deA q.O!f _2C
                     printf("optr入栈:[%c]\n",opr_in.ch);+A(R/jdSSv
                     c=getchar(); ET0JOO Mi
                     break;
IUBU v5}7G)d                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/;HUPgw0R |r8[
                     Pop(optr,e);
Em Q*Q5qS V,Gd                      printf("optr出栈:去掉括号\n");
aY]q$jfUN w_f                      c=getchar();
8k{ tl9E8o3p                      break;
w.\2G6F8H9]bv1e                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/.w't&{i/bo
                     Pop(optr,opr_t);E\C,J2tG2@ ~:j
                     printf("optr出栈:[%c]\n",opr_t.ch);DbU f;U#D!K!z5AwQD
                     if(Pop(opnd,b)<0) DH jb3ek3th
                     {)rZ^ xV GHZ
                         printf("Bad Input!\n");
J2a+XUe#Y&[EFgu2@7~k                          fflush(stdin);
~OVOQ2?7g.E                          return -1;-V6x!y4v7B
                     }l z~ge+JR
                     printf("opnd出栈:[%f]\n",b.data);B&v B4hl~
                     if(Pop(opnd,a)<0)
fvu{A~e                      {;M6otq0WGW
                         printf("Bad Input!\n");.O0p W*k'c F.g_
                         fflush(stdin);#y E.qsXwZ
                         return -1;t#a#Gh Of2lox
                     }t{z+K+t
                     printf("opnd出栈:[%f]\n",a.data);Q Y pdUj&j
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/`B4Io.P2Y
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
c"Y`+}/Q2Ts gi t                      printf("结果入栈:[%f]\n",opn_tmp.data);(yU&Z{"_ `)d6~
                     break;
$t H J-O5zoq             }%Pp$L3Q7P^SL+x(}j
        }'fdU/V(??,?g
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
`f [JTM/E     }
e#]0bqk7oU     GetTop(opnd,opn_tmp);YK&Od?.V`
    DestroyStack(optr); r6b|F~/d
    DestroyStack(opnd);
7mP GAqG     return opn_tmp.data;7q-`$@ F6l/x~s%x s
}
s.v/O p or0t
`z`FN6FQC char *killzero(char *res,float result)'q#N u `J/X
{ {vYT h
    int i;(w a{h!`+Ar

GJE&sV     sprintf(res,"%f",result); \:V ]BKL8Q
    i=(int)strlen(res)-1;"t'\y1L.V@
    while(i&&res[i]=='0')2n [&ODu{JXj7~2w]d7`
    {TN2L v5S9P%}7a
        res[i]='\0';t0B@8^9Jh\$i8c
        i--;k$I byX'C{x
    }
+XJ'x/l9G     if(res[i]=='.').Wu I]_4`#T9R{
        res[i]='\0';
#q5s i FFD     return res;
y@/X.?([2\0_\ } MX/S`0e
(H!]nJ+i
int main()3Z"o P)Bl
{E c&Z8?&~}9~
    char ch;!t-jW+qf d{
    char res[64];bB*_9?`9{ Y
    float result; jN"C,w(RA4n
    while(1)HE D.z8XTtu
    {
$\(?+u"U7WII         result=compute();n ]m{ym
        printf("\nThe result is:%s\n",killzero(res,result));
;RlD(b(m"j.F Y ]         printf("Do you want to continue(y/n)?:") ; jEO5v;]y'XQ,sN4WIg
        ch=getch();{9aTy;c/j
        putchar(ch);-vR0LNp9]
        if(ch=='n'||ch=='N')
^(nAK Kt,w|#C             break;
n:X,u;~P*p         else.E+[E1H4xzMg,ak
            system("cls");
.O.f$h x-F-Oi^     }
J e Y,Y5l&}v4J#W     return 0;
sz2j.Wsbb }[/i][/i][/i][/i][/i][/i]W$it"{*Cs
#jE ]+m6gKu!P
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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