#include"stdio.h" #include"stdlib.h" #include"calc.h" #include <math.h> #define POW 1 #define MUL 2 #define DIV 3 #define MOD 4 #define DIV_INT 5 #define ADD 6 #define SUB 7 #define MOVEL 8 #define MOVER 9 #define BIG 10 #define SML 11 #define BIG_EQAUL 12 #define SML_EQAUL 13 #define NOT 14 #define EQAUL 15 #define BIT_AND 16 #define DIFFER_OR 17 #define BIT_OR 18 #define AND 19 #define OR 20 #define Lp 21 #define Rp 22 #define END 23 #define OPSUM 23 #define Epsilon 0 int ch_char_int(char *data); int ch_int_char(int data,char *parm); float eval(char tag,float left,float right); int getToken(float *nump,char *box,int *state); int instead(char *box,char *express,int x1,int x2,int x3, int x4); float express_calc(char *box); /*-------------------------------运算符号的优先级的设置--------------------------------*/ int osp[23] = {13,11,11,11,11,10,10,9,9,8,8,8,8,7,7,6,5,4,3,2,13,1,1}; int isp[21] = {12,11,11,11,11,10,10,9,9,8,8,8,8,7,7,6,5,4,3,2,1};//主要是为了"("来设置的。 struct { char op[2]; int code; }opchTbl[24] = { {{'*','/0'},MUL},//11 {{'/','/0'},DIV},//11 {{'%','/0'},MOD},//11 {{'/','/'},DIV_INT},//11 {{'+','/0'},ADD},//10 {{'-','/0'},SUB},//10 {{'<','<'},MOVEL},//9 {{'>','>'},MOVER},//9 {{'>','/0'},BIG},//8 {{'<','/0'},SML},//8 {{'>','='},BIG_EQAUL},// 8 {{'<','='},SML_EQAUL},// 8 {{'!','='},NOT},// 7 {{'=','='},EQAUL},// 7 {{'&','/0'},BIT_AND},//6 {{'^','/0'},DIFFER_OR},//5 {{'|','/0'},BIT_OR},//4 {{'&','&'},AND},// 3 {{'|','|'},OR},// 2 {{'(','/0'},Lp},//13 {{')','/0'},Rp},// 1 {{'$','/0'},POW},// 1 {{'/n','/0'},END},// {{' ','/0'},-1}};// typedef struct node { float data; struct node *link; }stack; /*---------------------------------------------- 计算的方法: ------------------------------------------------*/ main() { char *data = NULL; int number=0; char box[12]; int state = 0; int i=0; int gt_re=0; float last_value; /*---------------------存储计算表达式-------------------*/ instead(box,"x1+(x2*x3)*0.899",11,2,1,0); printf(box); /*-----------------------------------------------------*/ last_value = express_calc(box); printf("%f",last_value); } /*---------------------------------------------------------- 函数的功能:进入堆栈 相关功能的说明: 1, -----------------------------------------------------------*/ int push_stack(float s_data,stack **stpoint) { stack *p =(stack *)malloc(sizeof(stack)); p->data = s_data; p->link = *stpoint; *stpoint = p;//这样才能进行传递。 return 0; } /*------------------------------------------------------------------- 函数的功能:数据出堆 ----------------------------------------------------------------------*/ int pop_stack(float *s_data,stack **spoint) { stack *p = *spoint ; if( p==NULL) return -1;//没有数据栈 else *s_data = p->data; *spoint = p->link; free(p); return 0; } /*-------------------------------------------------------------------------- 函数的名称:int instead(char *box,char *express,int x1,int x2,int x3, int x4) 函数的参数:char *box用来存储结果 char *express计算的表达式 x1..4计算表达式的参数1 函数的返回值:0表示函数执行的是正确的。 函数的功能:用参数代替标号 注意express表达式由x1,x2,x3,x4和运算符号 '+''-''*''/'()组成 "x1+x2*(x3+x4%5)" --------------------------------------------------------------------------*/ int instead(char *box,char *express,int x1,int x2,int x3, int x4) { int i=0; int length=0; int box_i=0; int data=0; do { length++; }while(express[length]!='/0'); for(i=0;express[i]!='/0';i++,box_i++)//因为这里已经加了,所以说box_i是最后一个位置。 { box[box_i]=express[i]; if((express[i]=='x')&&((express[i+1]>='1')&&((express[i+1]<='4')))) { switch(express[i+1]) { case '1': data = x1; break; case '2': data =x2; break; case '3': data = x3; break; case '4': data =x4; break; } /*-------复合语句实现的是把数据存储在box[box_i-1]后面---------------*/ { int k=0;//存储data的位数 int temp=0;//存储data的中间变量 int j=0; temp=data; while(temp!=0) { k++; temp=temp/10; } temp=data; for(j=0;j<k;j++) { box[box_i-1+k-j] = temp%10+48; temp=temp/10; } box_i = box_i-1+k; } /*-------------------------------------------------------------------*/ i=i+1; } } box[box_i]='/n';//整个计算式的最后一个字母是换行符。 return 0; } /*-------------------------------------------------------------------------- 函数的功能:计算表达式 函数实现的过程: ----------------------------------------------------------------------------*/ float express_calc(char *box) { int state=0;//记录box当前的位置信息 float number; //出堆栈的数据存储 float tag=0.0; float right=0.0; float left=0.0; int gt_re_value; float last_value; stack *num_stack = NULL;//用于存放数字 stack *tab_stack = NULL;//用于存放计算符号 push_stack(Lp,&tab_stack);//首先把左括号放到符号堆栈里面 while(1) { gt_re_value=getToken(&number,box,&state); if(gt_re_value==0)//表示的是返回是数值 push_stack(number,&num_stack);//存储数值 else//返回的是标号 { if(osp[gt_re_value - 1] > isp[(int)tab_stack->data - 1])//进行优先级的判断 push_stack((float)gt_re_value,&tab_stack);//对标号进行存储 else { /*--在这里进行判断*/ while(osp[gt_re_value - 1] <= isp[(int)tab_stack->data - 1] && tab_stack->data <= OPSUM-3) { if(pop_stack(&tag,&tab_stack)) return -1; if(pop_stack(&right,&num_stack)) return -1; if(pop_stack(&left,&num_stack)) return -1; last_value = eval((char)tag,left,right); push_stack(last_value,&num_stack); } if(gt_re_value == END) break; if(gt_re_value == Rp) { do { if(pop_stack(&tag,&tab_stack)) return CalcError; } while((char)tag != Lp); } else push_stack((float)gt_re_value,&tab_stack); } } } if(pop_stack(&last_value,&num_stack)) return -1; while(num_stack != NULL) pop_stack(&number,&num_stack); while(tab_stack != NULL) pop_stack(&number,&tab_stack); return last_value; } /*---------------------------------------------------------------------------- 函数的功能:1, ------------------------------------------------------------------------------*/ int getToken(float *nump,char *box,int *state) { float data = 0; int num = 0; int i=0; int j=0; int flag=0; while((box[*state]<'0')||(box[*state]>'9')) { for(i=0;i<OPSUM-1;i++) { if(opchTbl[i].op[0]==box[*state]) { for(j=0;j<OPSUM-1;j++) { if((opchTbl[j].op[0]==box[*state])&&(opchTbl[j].op[1]==box[*state+1])) { flag=1;//说明是双目运算 } } if(j==(OPSUM-1)) flag=0;//说明是单目运算符 break; } } if(flag==1) *state = *state + 2; if(flag==0) *state = *state +1; if(i==OPSUM-1) { if(opchTbl[i].op[0]=='/n')//说明是最后一个 { return opchTbl[i].code; } else return -1;//表示的是表达式是错误的 } return opchTbl[i].code; } while((box[*state]>='0')&&(box[*state]<='9'))//说明是一个字 { data = data*10 + box[*state] - '0'; *state = *state + 1; } if(box[*state]=='.') { *state = *state+1; { int dex=10; float count_down = (float)1/dex; while((box[*state]>='0')&&(box[*state]<='9')) { data = ((float)(box[*state]-'0'))*(count_down) + data; count_down = count_down/dex; *state = *state+1; } } } //printf("%f",data); *nump = data; return 0;//0表示的是返回的是值。 } /*--------------------------------------------------------------------------- 函数的功能是实现:左值和右值的计算 -----------------------------------------------------------------------------*/ float eval(char tag,float left,float right) { int n; float result; switch(tag) { case POW : for(n = 1,result = left;n < right;n++) result *= left; return result; case ADD: return left + right; case SUB: return left - right; case MUL: return left * right; case MOD: return (float)((int)left % (int)right); case DIV: if(fabs(right) <= Epsilon) { printf("除0出错!/n"); exit(1); } return left/right; case DIV_INT: if(fabs(right) <= Epsilon) { printf("除0出错!/n"); exit(1); } return (float)((int)left/(int)right); case BIG: return (float)(left > right?1:0); case SML: return (float)(left < right?1:0); case EQAUL: return (float)(left == right?1:0); case NOT: return (float)(left != right?1:0); case AND: return (float)(left && right); case OR: return (float)(left || right); case MOVEL: return (float)((int)left <<(int) right); case MOVER: return (float)((int)left >> (int)right); case BIG_EQAUL: return (float)((left > right) || (left == right)); case SML_EQAUL: return (float)((left < right) || (left == right)); case BIT_AND: return (float)((int)left & (int)right); case DIFFER_OR: return (float)((int)left ^ (int)right); case BIT_OR: return (float)((int)left | (int)right); } printf("表达式有错!/n"); return 1.0; }