捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
Ge%@!BHg nS 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
M1lZ FO_mK /**************表达式计算器************/
'X'{or'}"X8Nj #include <stdio.h>
9@"teC&K-Z2gd #include <stdlib.h>O.}7k1_b1T
#include <string.h>
cqL1_SP%h #include <conio.h>
PeY~-P oe/_&x'\ YE(l #include <malloc.h>m:CE"C1r z!e2J3zA

nwW!gIZ #define STACK_SIZE 100
-M+YcyS4`6D #define APPEND_SIZE 10
;v Uu+V|(\"` eL
3Ly%^F,y*ot struct SNode{O8@ J]*_L!tg
    float data; /*存放操作数或者计算结果*/ } ]$oW|X
    char ch; /*存放运算符*/
k'e[$i1e%w/y9g };
v7[3{ K!R vO!{tC8|6Is4Sn
struct Stack{
0s'v-a`A/B*b6P6R     SNode *top;%WNu$O1j3{a0o
    SNode *base;
%p}n0S Y\E9{     int size;AX|coh
};N _O!d E8J

0tli2K1A A4|v k /*栈操作函数*/
0tk'S}ZE4EQ int InitStack(Stack &S); /*创建栈*/9szwo*t
int DestroyStack(Stack &S); /*销毁栈*/*}"~9~y p+z i\;G
int ClearStack(Stack &S); /*清空栈*/&e;f;Q$} v6W j"[(e~
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/7\/`~0{fv
int Push(Stack &S,SNode e); /*将结点e压入栈*/
.HIF]Y]:K] ]"Z int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/z.pHVO6m8np

p:J3CN%| /*表达式计算器相关函数*/"q#M0Qhy({ T
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
$G6w}5[7SS#k int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/P!RA t9` {
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/[t'@Nn;|c
float compute(); /*表达式结算器主函数*/
fdOZLa~c Y|.ri char *killzero(float result); /*去掉结果后面的0*/
4@}xvN0@*h 2q8C+^7^y,B
int InitStack(Stack &S)1nkz*[`?"v"g!z6V
{
]KF&c:?v)M%u7]k;h     S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));B0ZE h!kYb+A7e#F
    if(S.base==NULL)
!}GBl5aE!lh     {|9@ e5m/M4TD+Elt
        printf("动态分配内存失败!");g;m6d;}l!vsr0F"cA#z
        return -1;
C3kmg-K     }%QyG*p{K
    S.top=S.base;5e$qY2f5^~y ~"W
    S.size=STACK_SIZE;8SktVg }
    return 0;
ew\6j? }
-y,i4k&~hLbc+\
!qO$d%~mG9P int DestroyStack(Stack &S)
"E3TpT4? R i)Cg {
G]i _7ls~m]     free(S.base);
q8n)a$t]'d9O cT     return 0;
#s$aY)g5|"A7[$rXpO }!kgHpFW7C&m

/hc:M'q s int ClearStack(Stack &S)FZ)X2r2E)|
{8H5Z-Vp q-S r J
    S.top=S.base;!q)ogx p0By
    return 0;
P9EyN"U f&_T4S-XU }g2UG4UD&[

3j/zN%{~:ug int GetTop(Stack S,SNode &e)
W#N;yl!TF/z \M {Ur6jz*o+?+O WB t8C
    if(S.top==S.base)
#qr,w@W,M^Z!\&C     { n;D3V W-e p
        printf("栈以为空!");8e,{}k0R;OD
        return -1;
:n"Xj Em f[     }
5Bf*qc5~N     e=*(S.top-1);
c U'R nW TH?qF     return 0;._qJqO7N
}0V2T1k'x pI8\
#[P,O^;L M8Yv
int Push(Stack &S,SNode e)
1J"~)E(hD\.q [ {
)zP AYG/f     if(S.top-S.base>=S.size)!Y_xS#x^,g/b6hjL&g
    {
5tolM!x         S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
KQ&k'y#k         if(S.base==NULL)
-gm,U:X;m+o(A         {|-k)u+\u7rC
            printf("动态分配内存失败!");n}*Kg:I
            return -1;eD${;m2v3aJS\
        }STR}!QtV
        S.top=S.base+S.size;~W]h l'`k
        S.size+=APPEND_SIZE;)`'TE$y.k8B4Y9X
    }\1K c {7`7oJ
    *S.top=e;3~r5q wq/YL
    S.top++;wQiW8?4hV H9I#{7Us-o
    return 0;
cNH#AD%d }7`'y xw"fZ\

5H{4yu5y*}2V"M int Pop(Stack &S,SNode &e)
n7R"J-w)M5n {2Jkj%|.\n {,j0K$m8T6^(L,B
    if(S.top==S.base)5w BL l8^:FS(J
    {2E+F9\ GC
        printf("栈为空!");UC vP cL/G_PG
        return -1;X3Hzy2r
    }
2WM@b:Em X^     e=*(S.top-1);H;f,i)S9D2Z
    S.top--;
F{-P rD.@     return 0;z1~?j&N-{ A
}RZ2D9iwH(Df^.n
ixb#\M
char get_precede(char s,char c)%AS"\4A;b&N%Q!b:I;V
{z9ci N6`d5W g5Z`'t
    switch(s)+UF trW)N`L
    {l RT$lod!iSey
        case '+':                 
(a7HL1c9s#NfHlE         case '-':
S;S)a:uZJ"g @p7Xih              if(c=='+'||c=='-')
1_0T%u)y-uXu                  return '>';$R6dKPx S j
             else if(c=='*'||c=='/')
[?fZ g6a%A7a"f S pg                  return '<';
Y3r#v;]Q ~              else if(c=='(')
NE@#}0U-tkne'zH                  return '<'; Tfv5Z@lm
             else if(c==')')
T/\g| c:B'FC o~-W                  return '>';
0Zj,C S7u              else I+F:ZzZ:dL;K
                 return '>';
t U:i%di?^L         case '*':!Oy%Vmx
        case '/':$Dwc*M*] G,eU:G|p
             if(c=='+'||c=='-')
#w-_nriA9LVc                  return '>'; ZO ^^6e-E
             else if(c=='*'||c=='/')
b!kNly/H                  return '>';
4q5e H.I:uV:B              else if(c=='(')7YX`tah
                 return '<';
"?[aI:Y:dbQI              else if(c==')')6gM4e'X-T#Mr$sl
                 return '>';S\ |0|0eL
             else
S E+l8A&aH(o;O b/R                  return '>';
:E.zx{'t         case '(': uo\{,b Jw1A t,QD WW
             if(c=='+'||c=='-')
OF!}5Bt*i,B                  return '<';
3zoLQLe              else if(c=='*'||c=='/')
-Z#@q[tb                  return '<';
'}/K h!Lu5[/A f              else if(c=='(')#S"wjnU&u v
                 return '<';b c!K_w`;cu)v#g
             else if(c==')')DO%C7J;^z t
                 return '=';
`0{;mKN9H,sM              else
7{*t)l9g6`])Fs1fm                  return 'E';9}f c7Y4N
        case ')':
dl$S9H+L1l:kkD;C              if(c=='+'||c=='-')
gJ%A3N6tL.b                  return '>';*bgfm'J9Di8F?N
             else if(c=='*'||c=='/')
*Y+P-@@3v/FL                  return '>';2^4Y*B~pqt-\j{*t
             else if(c=='(')
h2a(?4e1j                  return 'E'; tPr&p_v[J
             else if(c==')')
v?eP`                  return '>';} VF/~(q.\e Q I
             elseYw)^{#AH4h
                 return '>';
+H6[D%aZ,ha1|         case '#':
,] P `})k4f              if(c=='+'||c=='-')
H`9L5\ ]D                  return '<';
5nH1HH2x&^z Yo              else if(c=='*'||c=='/')]3c1TX{t+l
                 return '<';
R{| \/vu9BJ              else if(c=='(')
#z _Kx.n%[y[4H2W                  return '<';n+h0yN?2R;Dr A9G
             else if(c==')')'?DO+i3q7}
                 return 'E';P1|b;^k@,w
             else
`)D vg\.yS#g[K                  return '=';
~ms9o j IU*Fz         default:
0R q:e.^2vot"Fmmn              break;
+]#D#~S,P"^"|0Z"R     }3v(L8@L ~}[4z
    return 0;   
5F7{``(K*J }R'R7y*L4Nbua

"[6o0l Eq:W g J int isOpr(char c)m5]2B G2` p
{O6e8T7]7hl/``A!_kn
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') \ p0lp'~
        return 0;5JN!V j+I5` L
    else :L'k}-q%hg/c0EE
        return 1;
b:F9VZ8cu y }L HeV2Q5{8k

r:S_IZ5@ float operate(float x, char opr, float y)
U9[jbc+S7oy {
`$j"U&m9s     float result; [ {'I l6Tj4r i
    switch (opr)
"A:Wz^&owo     {
2LD"U"CQ&?4H*m         case '+':
*rl,r1{rL[0Y~*y              result = x + y;\ ?4w3U1v NS.po
             break;
J tTx#\_S8Z'Nh!O         case '-': s/R4Js2ab1EGo
             result = x - y;
{+[ Rqk*\ }Ly*n              break;
"`3A^Ro#XoP         case '*': )EfsRU-_D[u
             result = x * y;
-? D Q8L@              break;'So'vFxa
        case '/': @+q9Z,ZIBA9^ ?
             if (y == 0) r1I:Y_8i i-}
             {
Z _2^/]P                 printf("Divided by zero!\n");;g7iX7m!Gu*N E
                return 0;
Im'c,@g ^x              }g,c a J ha4k$T
             else#zX+[k)Or
             {
2P4O*y!m!H^k*x                  result = x / y;{j;|&W+j,eE
                 break;
|"j s Wxac!a7J              }'p^4H&GPlJC@B
       default:
S$?\/e5^)\              printf("Bad Input.\n"); ;s&OaC"I5l5mC
             return 0;*G?~$Hxy
    }
D hIj;U az%}+D*gD     return result;BkcK2x;@
}   
bBX W4a6y
Y2h0`5m&a-X jS float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
T,Ij1d#m$b {Q {9Ak ]dCc
    Stack optr,opnd;
Z(Z+sPv,Cb e%m$`}     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;a"nB ?*J*v
    char c;"I+Dwn#yH:n
    char buf[16];
g YG7\ ?d     int i=0;
0]bik0C T:efGLQ     fh L#E(p"U9f+m
    InitStack(optr); /*用于寄存运算符*/.bGOu5wKC
    InitStack(opnd); /*用于寄存操作数和计算结果*/TQ y_ VH _o~/^@
    memset(buf,0,sizeof(buf));5TU MBUdW
   
O+| }u1V(_l(k     printf("Enter your expression:");7@l O(~ Ry3j
        a1?f9b1W8L-|"m-\"D
    opr_in.ch='#';
?/MHp(U$`'v4u     Push(optr,opr_in); /*'#'入栈*//Uf3G/A']n&o
    GetTop(optr,opr_top);
rhj*c"c%s@*g2Z     c=getchar();a ]!c0f!HMQOp
    while(c!='='||opr_top.ch!='#')FXR3jXriV%l
    {3}"A@+b&s)~
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/!v$}a7l[n;l
        {)blLwKPJ#u iy0P
            buf[i]=c;R1U.\-E&u })ET:y
            i++;
@)I%e8oY%c             c=getchar();
1Ea+x7Y{}         }
0m#T.K%bW;W Vk         else /*是运算符*/
6h_#Gr W5\         {s|IM8W"c?
            buf[i]='\0';'FuS)G'oRY)t
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
R+ttm ~L;yP6gA             {I3k2~%|$O{
                 opn_in.data=(float)atof(buf);
6b#ly d&~j3_:s*p                  Push(opnd,opn_in);
mP2kz fl&_"S pQb                  printf("opnd入栈:[%f]\n",opn_in.data);\$p)P3qT/N/~9m9_ }F
                 i=0;
A'gr3T#o3q;i\%I%k9w3V                  memset(buf,0,sizeof(buf));
&}%E4[/bY.K&l)v             } NPNn%x p
            opr_in.ch=c; IToki+T/N;I
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/p9YiXy1OX
            {2l)cU*`w:S
                case '<': /*优先级小于栈顶结点,则运算符入栈*/
9{bfvzM7~d                      Push(optr,opr_in);~x6Enz x0~CQI
                     printf("optr入栈:[%c]\n",opr_in.ch);xX6d[%^Xe
                     c=getchar();
C!O^SPi                      break;
5jjMG(e                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/E9l]o q.U8{!Q7o
                     Pop(optr,e);jdf,D oQ"i
                     printf("optr出栈:去掉括号\n");
CK X;Km-~&Y0mO/q`%Q                      c=getchar();o%Y;i){8k8^
                     break;
y8L6} C:_$FDZ                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
h/d!C#Y~.d6E/U                      Pop(optr,opr_t);
9[7WKi ?S`w                      printf("optr出栈:[%c]\n",opr_t.ch);
v~ I nE/X'n                      if(Pop(opnd,b)<0)m*Jk$as2p E5d)_
                     {xh-p7Zr BnM^6w
                         printf("Bad Input!\n");
'^)N `&f1gn                          fflush(stdin);NND1K0VA M7S [
                         return -1; X8C9@.H7_X#`$LWH
                     }
2KU~LE_                      printf("opnd出栈:[%f]\n",b.data);:kX'X?t3mRK
                     if(Pop(opnd,a)<0)|R3}+Y4T.bl)v
                     {L!`]4A%S
                         printf("Bad Input!\n");
Bqk H,b1z'Qt4ur'yg                          fflush(stdin);b1q?vAsQ
                         return -1;(Za'Y8}@n
                     } [,QS)l g
                     printf("opnd出栈:[%f]\n",a.data);4VvWu(M3Ld9oZ
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ kAr6k&u |
                     Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
xJ@$W \j5Kt%]c(r                      printf("结果入栈:[%f]\n",opn_tmp.data);j7Kx^(R
                     break;$^!O`%i[\
            }? r]_3Le?3n
        }
2F!K+aC5V;PDd         GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/                qg$\#sa0txLl
    }2`C4My G
    GetTop(opnd,opn_tmp);4U,b?xLp{
    DestroyStack(optr);
'|R1zZ)o*M     DestroyStack(opnd);
kp#EzP*c:{     return opn_tmp.data;7SjiLqC'K]u
}!Q7fQKC@u

m mk^/d9Qs char *killzero(char *res,float result)
#jt4iU9y'd"{Q {~8F$A"m8~tNIo"F
    int i;5Ge {*sO.z|
m'X pi$T|A
    sprintf(res,"%f",result);
3~,I R+| nH]m     i=(int)strlen(res)-1;"e y4b4c5j#p
    while(i&&res[i]=='0') \:MBM S o/w
    {
8z+l}Y:j4v(U'|1E:f'S         res[i]='\0';
R S_4|,o g1I`         i--; B9]5iTky)YZ`
    }
] J9B/|#hL     if(res[i]=='.')
(|1B|/B8AyT}~/z         res[i]='\0';OO2B2J:g'j4I
    return res;
%XH,v$cFO]s tA }
\4il8y p.Z/z ? S \
P~z Z"u ly int main()5j?q%d b9TR
{
&AA1oDn.l0I:r     char ch;
j lw"A a.N)y;u+}     char res[64];}1IR2Z9Q^AJ bB
    float result;m%n%]9i6OI
    while(1)?o Z0g s6X#\
    { AW WB'Vp@f4y
        result=compute();u _sY,\.L*SGr}
        printf("\nThe result is:%s\n",killzero(res,result));)[2fcGq3NR(l
        printf("Do you want to continue(y/n)?:") ;h2q y'r U:T'{"wK f@5g
        ch=getch();
7b6~[*o%I+_lmdV         putchar(ch);J#Z\3g&TvA
        if(ch=='n'||ch=='N')
m h9xsv:dr             break;` d9d3s%N)P
        else
"C*dvR8\)a/p             system("cls");,hWT:e'h:Feh I
    }n]i6h-Oz_
    return 0;
%vx Y \'R d$f }[/i][/i][/i][/i][/i][/i]
E7I+}kZ.W`*x
[ kb{'ib-J [[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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