捌玖网络工作室's Archiver

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

C语言表达式计算器

为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. U"H9YJ D
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
(u8\NvG$U@V7p.ZQ /**************表达式计算器************/
KFr8@Y8Z4NVB y #include <stdio.h>
Z2Ek3Y.Y D f+^ #include <stdlib.h>
&z!f!I&D4v2G #include <string.h>*Xe's$n!u
#include <conio.h>
tD5B^ U Rv #include <malloc.h> Ahy0GB5U t:dH2t

E/kCx$D:Y&C)} #define STACK_SIZE 100
lJ6o,w:L&O _/h #define APPEND_SIZE 10
1S0N f1X0vS6X 7b%lu8uz%sA5k
struct SNode{
,J(q9Mh(ag#k*i9o     float data; /*存放操作数或者计算结果*/
0m*{8?9G8k Yc@     char ch; /*存放运算符*/
nw'?a5q0H Q;P,WV\ };1^Wkw$o

*q:hte lF struct Stack{2|dH7u"g;?};n_
    SNode *top;
8yc)^d9U'}p%H     SNode *base;:S5lG7BNG|I)lmMO
    int size;8O L'^W\vW l
};2@7u}8o {k{GP+R
by0k1o$u,rc"~
/*栈操作函数*/
;p&i)ZD_ c'n i6v V2T3} int InitStack(Stack &S); /*创建栈*/.O.spg2e(d
int DestroyStack(Stack &S); /*销毁栈*/;X t/~*l/q
int ClearStack(Stack &S); /*清空栈*/[$](HF WV
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
M?;i^;W @ H$Yi int Push(Stack &S,SNode e); /*将结点e压入栈*/
A#rx}-Q&w k-R K8yR bP int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ v[3jY0q1Py-P
$C}d]-JlN!pZW
/*表达式计算器相关函数*/ xHvl4Sq+e
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
.n c)Rh ka int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
{5czLu v TZ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/A6d*|&?6TO*Y$D
float compute(); /*表达式结算器主函数*/
&}+v9THO@q1]^ char *killzero(float result); /*去掉结果后面的0*/ @#d Zs.[!C3m!H

5w,hL2q.]+_,C int InitStack(Stack &S)eH4tq;^P
{1o&?/Nq|$d
    S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));n(q/H7`-] aso%s'^1Ljb
    if(S.base==NULL)
Q-Koa&Y D~Fg     {
tN7jvG2OD         printf("动态分配内存失败!");
O lw,Fg4vN,r [         return -1;A)~8u2mf ]#fd;B
    }
W;wQj'@/]b7{k     S.top=S.base;3h5^P^(B-jx2JfV6J
    S.size=STACK_SIZE;!ERa$SBTf9I9K
    return 0;^?4YNV+Kzb
}
;A^)a)K]Iy
d{ K$f%|X'x int DestroyStack(Stack &S)
7xjPC$~"`/y/G/fB$~ {
-Y#Ib?wuAP }     free(S.base);
1b S3E$p)As!lC {     return 0;H;ML'?c
}
6R2v:l9bL%x4w%@ +i1GF hH2YS
int ClearStack(Stack &S)U1H6h3{s2Sn,P
{
7p!WW dZU     S.top=S.base;)],bkj!Eb nq"s
    return 0;
aD A/|e _+B8e(q }fHF@ mfUv

*o.P5f%Paq%} int GetTop(Stack S,SNode &e)
;]%m7t fQ8L.iR)D {@/b%GF]-_;U
    if(S.top==S.base)? M&pT[+qP]'zk K
    {QBY`b5aA9e/z
        printf("栈以为空!");
u%X4X2U:]U         return -1;
*a7HPB7wSWo~     }
zsr\Sk     e=*(S.top-1);iDYTs1sI
    return 0;9SeU"yb!XA0[w+~n
}^y,[RyE"w
UY?s*v4Xcp"b p
int Push(Stack &S,SNode e)
"DR| ?`` {
tQk {(GkV     if(S.top-S.base>=S.size)
h:R9H:OWU$Rl o     {F)_7OXBf
        S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));gRn&n ]]0X9x0^]
        if(S.base==NULL)
$L1eX!O'E?}8y/Ydu^         {
r%r&jr4s NC1mdZ*~             printf("动态分配内存失败!");
|"Aen#Kf:DI             return -1;@+f9Sv [/qGP(y
        }N:kV$s.^+wa#X+aW \
        S.top=S.base+S.size;7Xw3c{.}9sY8}G
        S.size+=APPEND_SIZE;
0X,P iO"M;Vp pWf     } V&Zt*b)k
    *S.top=e;%viZ\6z*h o~5h!ah
    S.top++;
7t$C\H)xy.` A     return 0;
b]V0TR }%H(Z2O g$wLxW F

r[%y3Ww#ak int Pop(Stack &S,SNode &e)0[(d.ID-pLim
{M1[*X|!JKVf y O
    if(S.top==S.base)
X)c6X q:X"PX{     {5H0f`$n6H ]
        printf("栈为空!");
l3Nk C1Ca         return -1;Jpn!YZ2n1N
    }
c9Q V[iu     e=*(S.top-1);z+D7b9du8A
    S.top--;
}Em:EH%o I5C     return 0;
TOcYD9f3q5b }
8mRa:uYho3u n m"\ k7_1qX Q4a
char get_precede(char s,char c)
:T6e+z#e]4qF {
2K"T b6B"` r0oTN     switch(s)h"B-?!p N"|
    {.K;@z_.h h Q y
        case '+':                 
cMPI;r8NVw         case '-':
1z"wug*ee&V              if(c=='+'||c=='-') qMoGv5kr&j]5x
                 return '>';Leg}R3UR;[3e
             else if(c=='*'||c=='/')"K0W}:ga.P7i B7a
                 return '<';6Nyw PDf
             else if(c=='(')
0tL O s?^                  return '<';YL+zC%PE
             else if(c==')')
1]"v.}p?                  return '>';iz m9d%b~5Wa
             else 9? \z2W/X#y'j&i
                 return '>';
F'UD;rFv&a         case '*':
/E/M4j|@X3U-gK)`#j         case '/':f m"cUm
             if(c=='+'||c=='-'){TkhS
                 return '>';] R h} R$r~
             else if(c=='*'||c=='/')s$[!M3TN:Et7[
                 return '>';
Ze/w"^#ZbP              else if(c=='(')!pq4~y3D p
                 return '<';4s-V^"H,jt*t!U
             else if(c==')')Z.Z QP"@J-G
                 return '>';
N_,_bL(o,u!o%_:D0x              else+M q5b&M/e C
                 return '>';"L Tb6M-k
        case '(':
d;X8pIR|@ s7p.D              if(c=='+'||c=='-')
Jr#A V"wj                  return '<';5Mm%j H,C|-j F
             else if(c=='*'||c=='/')
R4\0?o*_:nA                  return '<';
5W0a/l IO*wu              else if(c=='(')
.\W R`2j:rr~                  return '<';MIgf5aj%H
             else if(c==')')+I%nMQAAXh
                 return '=';
!v+sP#D;s,a9I              else3A)]-HEz#OzN
                 return 'E';(JB|wJ$W
        case ')':
VD'E|!C _5XVU              if(c=='+'||c=='-'):];fPf*f [
                 return '>';
?4DQ5b MF              else if(c=='*'||c=='/')
bKRw"|g-w Nm(|8f                  return '>';&|3MD$z.z.^/Y-{
             else if(c=='(')
v9F#HtQ1a ? Fe2Fh                  return 'E';oTwuSM4CR;C0z)jF
             else if(c==')')
(F5\\V;N                  return '>';
%M4tG @ P?~x              else
@1Y ?MD,[                  return '>';
F&Bs [%S,f-I         case '#':
&FIS(ev&h              if(c=='+'||c=='-')p(mL,Gi8I
                 return '<';,f%l2hxV$Swl-X
             else if(c=='*'||c=='/')
H)uc(\2b2]ys}                  return '<';oogb+X(B
             else if(c=='(')&rGt$uq.ic5q
                 return '<';
1k a az5X2y?7E s              else if(c==')')
9^8N N6Zv                  return 'E';
x M3E+os9QUO              else
Gr]0}#C9_ B                  return '=';d"|(C'W zs(k t+W
        default:U&aM hwj
             break; qQ LJt w-g&a
    }){ v)NEL.q K
    return 0;    8\4\I8N#O'yb&As
}0H u?L i
E@1m'D/h C$q
int isOpr(char c)"Nq'n:?/dH*BL
{rL5r"X5d#Ss
    if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
F~a q;U         return 0;
XPV"C]_el$u:O     else 5` MR;PJ;lU
        return 1;
rAq8I}6G*byW }a~ Yb mB
I.V8^+O,p3~4B3QF
float operate(float x, char opr, float y)
)@J mZ?"\0I\7@ {
du o?ZU(Hs     float result;
n ^z1t!Z6]3c^     switch (opr)Z6Hbni{
    {-om.~"Y+c!u
        case '+': +Z'h'fJ p
             result = x + y;
1o'``vb h&wJ(h              break;,P/G[:].^3Wbj[
        case '-': }$gX:j%\
             result = x - y;
#_/]7K?6ee4h              break;
.B+M!\.x"X Q@ M         case '*': r/h]$`6n0fe
             result = x * y;
6yu6q"|1RrRN$Ke              break;Ax9\!F6l
        case '/': gG7{ZO"t
             if (y == 0)
+WoTS3D!E&r*jR              {
3E2m`xn$sjy                 printf("Divided by zero!\n");'o^(`.KlQ
                return 0;(IlO Vz3F%^b
             }:Ks/e$lrMv
             elseLl cf&jdh
             {9C\~#Z{,a
                 result = x / y;PY#Fa#GOI
                 break;
&k i'V!JPy9@ y| g              }&ZRtvY
       default: kp4a;J9ia
             printf("Bad Input.\n"); :B,^ ?`#vOO
             return 0;H)CMtd:[6@Q SR
    }#BHGQw,U
    return result;
/GL1` yUCA5X Id }   
$Z0c&Vb-\9? ri2@-U){Ouj,K3CK
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
W}+Dj9q"h\2f H#d-| {[#q{ h-r\$iY1W
    Stack optr,opnd;
B&`J[3d m_R     struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
D w5PcWW Z     char c;6N dKU\@
    char buf[16];
Ke+i:m!@4M6a     int i=0;,r*Z%|l/pl'ya
    NbQ9L%K'`4y2L,G)FK
    InitStack(optr); /*用于寄存运算符*/+G_!g5r a-dP s
    InitStack(opnd); /*用于寄存操作数和计算结果*/N {-F\&T&g
    memset(buf,0,sizeof(buf));
,J7~9}Yg&r I    
X,UKCn     printf("Enter your expression:");
mK)C r!z:Bn.n;]         
nd^gm%Ub.^l     opr_in.ch='#';
Y#YJ1},q3dt,k4f     Push(optr,opr_in); /*'#'入栈*/
e9B#m8m;UOV1s     GetTop(optr,opr_top);
,It7V-PK II c6i     c=getchar();
.VbE~I R     while(c!='='||opr_top.ch!='#')
6MP0^:Wu:`C$c     {o/N;| y? I^ k#L\b
        if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
r n O1i P7E2A'i F         { b9zq|@dF _
            buf[i]=c;&A vf G!Ho_
            i++;U*@s/`6fyW
            c=getchar();
%d%}qClw#d         }
+{Wk,oj{9{         else /*是运算符*/O#mx W8CN Va
        {Z5G-Z9RroG1m
            buf[i]='\0';7H8\3wR$?;Y*y+C
            if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
bQ$wCLArh             {
5K-a\ noVzr                  opn_in.data=(float)atof(buf);D.LXeU9H
                 Push(opnd,opn_in); XgHun^
                 printf("opnd入栈:[%f]\n",opn_in.data);
A*s#XHAM1e(u/myJ                  i=0;
"K%W8v,^fHZYRa                  memset(buf,0,sizeof(buf));Mq N-`7m
            }
w.|H3f.}]             opr_in.ch=c;2g0b'V xYf\9i
            switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/+bk+h|`b1X;DL
            {1aa0M4d0K
                case '<': /*优先级小于栈顶结点,则运算符入栈*/8W4r iX9gZ;h]o#]N%S
                     Push(optr,opr_in);
V3HMe{,[;K                      printf("optr入栈:[%c]\n",opr_in.ch);
(\ w]SRe                      c=getchar();
-V-h)q;b2y4|g ~;^                      break;
poM%|A                 case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ _m:Qd/ni
                     Pop(optr,e);
V2q,Ky0[/Tn~Z Jg                      printf("optr出栈:去掉括号\n");["p-T|2iJYie
                     c=getchar();
*^;d*\$cQ8KLy                      break;
HJ;B,g%kt$H                 case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/l5ovV D7\-eiT
                     Pop(optr,opr_t);
K)tC-b9O)dk4d                      printf("optr出栈:[%c]\n",opr_t.ch);
m)to'Gk/^)`;q                      if(Pop(opnd,b)<0)
F"q B"v} X&c(R9c                      {
$XE c;kpA{"Y)s                          printf("Bad Input!\n");
d3C*R?s!S                          fflush(stdin);
!`aqP%W9a                          return -1;
#Bw5H;[7?b)v                      }$qOZ-@7T%o+f%[;Qk
                     printf("opnd出栈:[%f]\n",b.data);
1VVD }$X)g                      if(Pop(opnd,a)<0) TmV"ZJ2m$B#T y(Vm
                     {8t!^r3E4d5o
                         printf("Bad Input!\n");.jm+Q"u)yQ^+d0C3^c
                         fflush(stdin);l#Z)_"]q5gK E
                         return -1;
~#r%@T ~8m4N                      }8c$^B:c4|t
                     printf("opnd出栈:[%f]\n",a.data);k'Q7G q BX^N
                     opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Lr c!^*^:MA%r                      Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/2P gZJVXR.a,p0N
                     printf("结果入栈:[%f]\n",opn_tmp.data);k&PNE }sU`
                     break;
+bI:Ye?*g'eyd             }|F8_%bb4tb6}6OY
        }3g {VWH6n;s*B
        GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/               
`t2I6~ \H6c,h U)o7z&M7u     }'D WUn"\*Kq6x!QC
    GetTop(opnd,opn_tmp); x&kh ps^
    DestroyStack(optr);
0G0X3W@Y     DestroyStack(opnd);9j!K\Gb b H6_Y)D
    return opn_tmp.data;0kuQc.F+w*Pn(Q}
} D4?y)|4`M4K
4r(t\ z FS
char *killzero(char *res,float result),k5ZD-{#RL/}:eJ
{-r{%P/J Sb
    int i;w;n3a!D p

| zgMB2g0m4v'\"cO     sprintf(res,"%f",result);7C|,n2C i&P$\-z
    i=(int)strlen(res)-1; { _a4U-Lu9Q9I%c'b
    while(i&&res[i]=='0')
OP4f5C,{-s     {i{5x/[;s
        res[i]='\0';
T6h X Y[j]$b;m4M         i--;t@'v N pH;?(i
    }2E0w4tD.L#Y
    if(res[i]=='.')
nO"Cx0F"`6Vn6r         res[i]='\0';_$cL ]A.D(M
    return res;
(sd)Ccze K2k }S]sK-wJ
+t1Nm1e O'XhPx
int main()x)?b;U5M
{
DYegT/f NHz y     char ch;
\.b S(k0_4i     char res[64];
|1W s"f+tQ     float result;+Q"Sd b8~4D-V1i3J$c
    while(1)!H N;Q;u Y&M![6I
    {
up2nhf.o-?         result=compute();&Hr QGKs
        printf("\nThe result is:%s\n",killzero(res,result));
2V[2@3?7Ny         printf("Do you want to continue(y/n)?:") ;
co[}QB UW         ch=getch();
X,_f~4~p ar         putchar(ch);NUN^X2G
        if(ch=='n'||ch=='N')
7{LT8G&V"Q.m^             break;
u-XNp8F0q'G         elseu:sv:Ng8M
            system("cls");p/EH5r7Xk
    }8Ev;p bSDT
    return 0;1Jy HuF"q
}[/i][/i][/i][/i][/i][/i]
u5J~*Bo0L7jcB? x[m.{G^
[[i] 本帖最后由 zw2004 于 2008-1-21 17:21 编辑 [/i]]

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


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