捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. ~{&j lxa&CP
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
`x&[so"~RW /**************表达式计算器************/
pM k/pgk#R0cX #include <stdio.h>
S+z"w(tad6A} #include <stdlib.h>pV X@/d+B:Oo9O7[.^K
#include <string.h>
-`&LD(?T_ #include <conio.h> An+EU XD
#include <malloc.h>a]t*M~AgN1{
?'?/yn l4O2_
#define STACK_SIZE 100
Vs@ W+l%H M #define APPEND_SIZE 10
*P8?G]7ruVL ] nf)po2@wv"g
struct SNode{'Ic0G)o_*E \S3w(^V
    float data; /*存放操作数或者计算结果*/
;DXXAm~cSQo     char ch; /*存放运算符*/
IOHT1B)g+?,d };e-H|!M'c1Rgfq

G.x{4k,U'{ struct Stack{
#MaH[4~:T~ U:\S     SNode *top;
FJlxYG'v#^8@[;Q     SNode *base;+h4DJ-G:w
    int size;
9k0KM)\0W3{u };
6_7^!_D"nw%~/[?
9k"|P8fF8k;u9r /*栈操作函数*/cA#[L1Q h^n
int InitStack(Stack &S); /*创建栈*/
y%|x$xL8o,w%gtV int DestroyStack(Stack &S); /*销毁栈*/5o8^O"F$VTc0s0J
int ClearStack(Stack &S); /*清空栈*/3}Wg4sl)Dy2E
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
#X7Q6V-nPpq#g int Push(Stack &S,SNode e); /*将结点e压入栈*/
5A bL%it9O"_:Y int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/H+F4H:uw

7b _lV+~8dxu /*表达式计算器相关函数*/Qaf7`4})`;U
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
4FLP/Im$T int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
-h~}*d Q float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/Z_o-O"X;T h'G{
float compute(); /*表达式结算器主函数*/
6H#Iqo1m2[7W v char *killzero(float result); /*去掉结果后面的0*/
DNx0o_Lq [|e0b#q6[$c
int InitStack(Stack &S)
Nh'L*Qu i#Be:m {
3f\.Hf y0B WE3Y(D.Y0P     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
H I'fs*c0b%J     if(S.base==NULL)W2Q_}S!l
    {
d^e/Bal         printf("动态分配内存失败!");
L!Ndwv5h-W         return -1;1q$n1}#l d,crG
    }
n0y\oxnqYq5J     S.top=S.base;xzL,Cn{[q
    S.size=STACK_SIZE;8J1[*T"W*K{Dp'~
    return 0;
3f0h;_-nTA!tgf3g }3PW }M:[by4_ b

:O$C b?kvj int DestroyStack(Stack &S)
ab6?:S*ss'h { a:c#rB8KL
    free(S.base);
5Ke!D.ZX Ui F\     return 0;
t+Gt:G#qD }
?2U'YemVV y6`z+}:D0@YM
int ClearStack(Stack &S)
} a6f l5ay m!o,\ {
_/Ts+t[1T]PE     S.top=S.base;)u6_ q\0Y(M:@-}b
    return 0;
$l9^s2q{f }
\ | f5Ok"i
5IiP+n0gvC'GG int GetTop(Stack S,SNode &e)Zpm `(sE9h
{!`8W4O%n} M0Jd
    if(S.top==S.base)
(r*zoj}&S,XV!aY     {
s*@`%UI2Z`*c'a k;]         printf("栈以为空!");
,i#^F:sL N5RY         return -1;
!s U;BMc     }6EZ_2w4U7TJ
    e=*(S.top-1);
[YR:A `Ojd h     return 0;k.U(K.^)xD7KS(h2v
}
'd-X,m0T:K]G3v:Ly\'g $Cf'L7T!Z&J
int Push(Stack &S,SNode e)8H lt0Za)Q
{,e q5qU-G+C
    if(S.top-S.base>=S.size)
0}j-sCq%zL     {
^D4g0F3@)a         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));W]]F)xXX$O
        if(S.base==NULL)
sm['Bp9S         {
@ZVk0^+ZN1I@             printf("动态分配内存失败!");
2mg4LB/z:s&WcC             return -1;2d!`0u8g h&rN[
        }
3[7]#a GLI         S.top=S.base+S.size;B/I2[6EQ
        S.size+=APPEND_SIZE;8A Q6Fl Y(gaY
    } ?iu"Yq'CJ.H h(G
    *S.top=e;+BB _)@U CY
    S.top++; e:l"bV8R8i4K h+eS
    return 0;7J2O G+a#_F
} `?y t&z+Zr%g!J!i+w&x y

+Z!\ u8C%h int Pop(Stack &S,SNode &e))N3e_l(h/i#dZ
{O%n6W ]$I W De{7^
    if(S.top==S.base)
!hA-s,I&M&Bg#^,h t     {
&P#N/Mb;V&V%u%v TB^6E         printf("栈为空!");
-I#V MIy O w         return -1;zL-sa)~XB:k,v,a
    }
!@?Z*q*x9x_,Nl     e=*(S.top-1);
$NS#gy[,NJ     S.top--;
W"T4a(TJ5j-`r     return 0;
\ ZT9L"`6m|D3t n }+G| w@4jwk2X

`']o1H } q'^7t2e char get_precede(char s,char c) ]A%p7G vkkc
{
4NL4r xl b3LTp'qr     switch(s)_*F1v?(t+`.a-}
    {
l Rt`I/u7y^         case '+':                 
-P,kag&R;w         case '-':
8X,|I$N"R"G              if(c=='+'||c=='-')'jX'[dW:Y$|
                 return '>';dvL`;DLZ
             else if(c=='*'||c=='/')\ PC Pg6V0n^
                 return '<';JAt!A)f
             else if(c=='(')
)ax_*j)^X                  return '<';
l#g#[ZDld.i              else if(c==')')
ck0K+MPm Od4dF                  return '>';
pK/UmLIvM Oi              else
:z H!Q:NxfN                  return '>';&i'R2O.m-e{b"[(z
        case '*':
+vv6~1oXe(P N         case '/':/c N*B6bF TA
             if(c=='+'||c=='-')
b;[E"E4m:\                  return '>';
+K0fS-wm g#k1OS              else if(c=='*'||c=='/')Y(J^\3Qk]Tc
                 return '>'; @YLsc.V3v[
             else if(c=='(').W)X$I"@HH
                 return '<';l(s(X^*mJ
             else if(c==')')8R3a.GV-Mu s
                 return '>';
P i"C,_|5y8e              else
K'U0fQ.i+ru                  return '>';
9v-d!L#pnqtd J         case '(':(d0E|:k0U
             if(c=='+'||c=='-')
/X+b0R Ne%|'\                  return '<';&Af6l6p~.Re
             else if(c=='*'||c=='/')| tU![,X'S*O4W&z2H0q
                 return '<';&_FOG-gb
             else if(c=='(')3bGanS;p
                 return '<';%H%x ^a#G"yuz/_Fu
             else if(c==')')
%Va e2^3j0a;w                  return '=';
+p;s M L!j u t Fu e              else;Y6mw'ZS8Y lc
                 return 'E';UMf C1v7B:D [0A
        case ')':
C T9O s%AF1@(ex              if(c=='+'||c=='-')D3i`c K8u cyJ!VY
                 return '>';
/d7DN#bTpN:XYCr              else if(c=='*'||c=='/')wd9eE,[7I
                 return '>';$o*y7g,`_"CL
             else if(c=='(')
$[0J.^'D0D ll                  return 'E';B#? {#X eg
             else if(c==')')9^-Li1kj*a`
                 return '>';
w+|"i4NK L              else
]u9u8WD,b1N4m5h`w                  return '>'; Hpg:w*P ~'D9H,I}V
        case '#':*} T8Nm h_$Pi
             if(c=='+'||c=='-')
)NU yt-zO)z.B                  return '<';mJ]5a \AoPo
             else if(c=='*'||c=='/')6_-{$pnMjD&N
                 return '<';x|2e(?8_-i
             else if(c=='(') iF] uz(dU
                 return '<';-K*i|P#iA` mh(\4J"h
             else if(c==')')S"X9zcr"^!xM2l+yq t#Q
                 return 'E';/W7vsk.F2|y-B;G,p9a
             else
$uo6LC+H d$Y|z                  return '='; c(})cv!I3@9Z
        default:/T.v#E K2c:~!_{5e
             break;-qcM9j;W2hy ~T4Z
    }2VKSDlU:_G
    return 0;    Bhrs)@v w:@n(T-Y
}
NR(aI E"I .n;Id/U6A&j
int isOpr(char c)z!RfcHi7Ad
{
2s%N%Q5^"u^~mc     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')-`2o2A [(P^ j?a
        return 0;cJ$N`1h*o+kG0N
    else
*?g8J#NXj AE         return 1;7~T;j(~&j1Vy6j
}
WAMk0ML8i*H s9KXL~1Y
float operate(float x, char opr, float y)ee:D7~$wF^1`
{
NTbCW0Kcv     float result;gR {{1v9m
    switch (opr)
1jOWe RvK/? l-i     {
O-Tc2XR         case '+':
#U:C8S!J/uF-m,`c              result = x + y;
T@?-XI tX1p              break;g{"c!NF.[t1{0FE
        case '-':
B1i6m yPit              result = x - y;
p!r G~jq              break;
v.LI7d)qS2m:F `g         case '*': #^UHFy+uY4k
             result = x * y;
xGkYg^&@:Y              break;
k!Sj@F"kAv         case '/': i~]sdK
             if (y == 0)
|2kT OC]              {+E_/WH#p;Q Z%W
                printf("Divided by zero!\n");+u(V'J*ZI4zz b+Y
                return 0;/h ~(bb sO
             }!Uk$M6MY;K$|$M YE
             else
PD&D"W f-\szjn7FV              {
9B5sW'~RkVU5K L:Pf                  result = x / y;3ghp[k
                 break;&e:|f(J ~IU
             }V)SZB5H|$w
       default: FT7C!RAb
             printf("Bad Input.\n");
~@ [-x@1qj              return 0;
,Uf"a]{(r gj7y#b"g?)N     } S X@Mb
    return result;O@D{m1\:O!p
}   
1q:b _%c K.G9A
pqM3q&|cqy7| float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/;cd ABW#O ~x`
{;J^6Bce5x:y'e0|
    Stack optr,opnd;
FC-~3t^ Qq:j     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
3C/JU\4]La{.\     char c;
rY2uk4h&Y:FH9fK^     char buf[16];
.J&Dz:c [n F     int i=0;};G{5g ]o }q!O
   
0y1W'A-xr S'`eR     InitStack(optr); /*用于寄存运算符*/
8`Ab,V8?     InitStack(opnd); /*用于寄存操作数和计算结果*/
|va]$jh u)z     memset(buf,0,sizeof(buf));V6Q6`"Y+} G i'FS!J
   
JL q%\*}.f     printf("Enter your expression:");g)I]Dm.a,B"R/w
        
Sgv Sa x     opr_in.ch='#';y/JT{+l6\
    Push(optr,opr_in); /*'#'入栈*/
(o5vD*|D`(FO7Z     GetTop(optr,opr_top);
q)V&E\#f2mA:nYK     c=getchar();
U5x9|8p\_"eO     while(c!='='||opr_top.ch!='#')
*yQ8T|J k-n/_     {['_/n1nkl!@r!t
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
)[7i.]E{         {
}I _3e9Yt^,]Z             buf[i]=c;
^w-? U'X:Z             i++;"UZXu t s"b d(v
            c=getchar(); SB1h?p7aT
        }
E W` v%y7a2d}'l%kT         else /*是运算符*/@Y&^ I0T x ow
        {1P!wIS#F
            buf[i]='\0';a"g,v-|wmA
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/E(E#p#^fF.^u'{'|3u
            {+Z5~fQa*J N
                 opn_in.data=(float)atof(buf);
B{#w-N _:i[ j                  Push(opnd,opn_in);lD9Ac-u4p
                 printf("opnd入栈:[%f]\n",opn_in.data);l;X~9P&e,G\9Z
                 i=0;
1gZ3l FPi d0]                  memset(buf,0,sizeof(buf));
0nC^!b4JPX             }
L#o%oyR]9r             opr_in.ch=c;
2_6~+axw7g9i3EVD%r             switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/Nmy"y&c@ @C.Z
            {h_+Z A(d@4O
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
/L2J @J m3}$W                      Push(optr,opr_in);
1Lt+C|'}Y                      printf("optr入栈:[%c]\n",opr_in.ch);
b JC6\dr                      c=getchar();
;\S@O^`|W                      break;
,Bc j6f"y7M B8k                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/0Na|K y%B
                     Pop(optr,e); pR(q,\'eg z
                     printf("optr出栈:去掉括号\n");1b,f3u]w6_;K
                     c=getchar(); { ]v2i_DZ'pa
                     break;
-ZT`&{B2lX                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
s6D;ixGZCA:RE6]                      Pop(optr,opr_t);k-?U(A+b+h4e
                     printf("optr出栈:[%c]\n",opr_t.ch);
@ l&mq7b&X9n]j:AA                      if(Pop(opnd,b)<0)\2f}'Ws*@1m
                     {
F#KP0m,J(R                          printf("Bad Input!\n");
6qT-Jg9QM)d9Ra:`                          fflush(stdin);
#T,o7jj|w&Z                          return -1;#Bwcs_ ACe#R!I
                     }zJQ+nU%g,lj
                     printf("opnd出栈:[%f]\n",b.data);!exN X}FByw7Z
                     if(Pop(opnd,a)<0)cQ6j x%u:h L%Y [a
                     {^0B!mE/? {
                         printf("Bad Input!\n");
ZO)W(m*z5Mt6i@                          fflush(stdin);1q.RK;l'u&~a
                         return -1;
;~{8H,a.k7cG0K_ v                      }t UK)r+l6SJ;yh e
                     printf("opnd出栈:[%f]\n",a.data);h/f\P0X-s3FX)g%o
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
iR(y9bn(o3W[                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/7z%E~;z,K;`bR0DT0x
                     printf("结果入栈:[%f]\n",opn_tmp.data);5}Z&iuv2U.w:A3Y
                     break;p K!f7TC
            }
N|[9@? q         }o CX q"h{:r8?,Zj"o{
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
!v:exn-AAa q     }&q0eoF%x Q
    GetTop(opnd,opn_tmp);
g1qo N/y x [     DestroyStack(optr);v1j#RA:O
    DestroyStack(opnd);
EJ0V3S6i4}r,h     return opn_tmp.data;0f*E8PM:e@
}
6hl{R]5qw,lG
1_'`J/J1x9i char *killzero(char *res,float result)
/j;}BgM6m3wA9S {aP&K s4y8_TA
    int i; X-jz$Jy2H

$xN"m `)Q1f"sF7m m*D     sprintf(res,"%f",result);
+XX.y g I7T6g0pF     i=(int)strlen(res)-1;N]7_ oU
    while(i&&res[i]=='0')
a;Wht f1H:]Tr     {3Xe\vD'b
        res[i]='\0';'B&K,t7k/}@
        i--;;`f"@)aX@`+Qp3v
    } j7o7h\F7AV
    if(res[i]=='.')@7m? v @A O;D
        res[i]='\0';m jWa#LY z
    return res;
}_vj,z9DT }
:a TF~"Ek vi
9wnV Wl int main()Z5pMb!y-D#I
{_-LEK:~hx)g
    char ch;
4Q8HlR6lqB     char res[64];
`\ |"gI_5E&_     float result;2G1H O)A@ Hc.c
    while(1)
;FT|qr zo:egr     { s9~}#Y"V MdNY
        result=compute();1Zh2m(}%xm
        printf("\nThe result is:%s\n",killzero(res,result));
,o^0} TY,C Z6vZ         printf("Do you want to continue(y/n)?:") ;
0s Tb-L"S         ch=getch();
^hk-c*j'JJ zDc[D         putchar(ch);/d QG/H*q
        if(ch=='n'||ch=='N')tBp oT
            break;
\S EN+kbK         else
7[&@G*pV(U1J             system("cls");
%X7E{j2BuM)@W     }
"^psUa     return 0; i:P2g(UX'|t+b]
}[/i][/i][/i][/i][/i][/i]
%J_-b-UFK,dda R]6L
|,x)O5hT [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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