为什么要实现四则运算,看是很傻比,但是只有你明白其中的用处,他才是有用的。呵呵~~~~~
简单四则运算实现:
#include <iostream>
using namespace std;
int fun(const char * pBuffer,const int &iLen)
{
int iEnd = 0;
int num[20];
int iNum = 0 ;
char str[20];
int iStr = 0 ;
for(int i = 0;i < iLen ; i++ )
{
if(pBuffer[i] >= '0' && pBuffer[i] <= '9')
{
num[iNum++] = pBuffer[i] - '0';
}
else if(pBuffer[i] == '*')
{
num[iNum - 1] = num[iNum - 1] * (pBuffer[i+1] - '0');
i++;
}
else if(pBuffer[i] == '/')
{
num[iNum - 1] = num[iNum - 1] / (pBuffer[i+1] - '0');
i++;
}
else
{
str[iStr++] = pBuffer[i];
}
}
iEnd = num[0];
for(int j = 0; j < iStr ; j ++ )
{
if(str[j] == '+')
{
iEnd = iEnd + num[ j + 1] ;
}
if(str[j] == '-')
{
iEnd = iEnd - num[ j + 1] ;
}
}
return iEnd;
}
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
char a[]="3*3+7+4/3";
int k=fun(a,9);
cout<<k<<endl;
return 0;
}
弊端:
1、表达式只含 +, -, *, / 四则运算符,不含括号
2、表达式数值只包含个位整数(0-9),且不会出现0作为除数的情况
3、要考虑加减乘除按通常四则运算规定的计算优先级
4、除法用整数除法,即仅保留除法运算结果的整数部分。比如8/3=2。输入表达式保证无0作为除数情况发生
5、输入字符串一定是符合题意合法的表达式,其中只包括数字字符和四则运算符字符,除此之外不含其它任何字符,不会出现计算溢出情况
yacc lex 是什么,自己去百度吧!你会找到答案的。
math.y文件内容
%{
int yylex(void);
#include"stdio.h"
char *mail;
char *cError;
typedef YY_BUFFER_STATE;
%}
%union
{
long long integer;
double ldouble;
}
%token NL LPAR RPAR END
%token <integer>INTEGER
%token <ldouble>DOUBLE
%type <ldouble> exprreal
%type <integer> exprint
%left OP_ADD OP_SUB
%left OP_MUL OP_DIV
%left OP_MOD
%left OP_NEG
%left CAST_INT CAST_REAL
%%
Program: exprint {sprintf(mail,"%d",$1);}
|exprreal {sprintf(mail,"%f",$1);}
;
exprint:CAST_INT LPAR exprint RPAR {$$ = (long long)$3;}
| exprint OP_ADD exprint {$$ = $1 + $3;}
| exprint OP_SUB exprint {$$ = $1 - $3;}
| exprint OP_MUL exprint {$$ = $1 * $3;}
| exprint OP_DIV exprint {if($3)$$ = $1 / $3;else {$$=0;sprintf(cError,"%s","/");}}
| exprint OP_MOD exprint {if($3)$$ = $1 % $3;else {$$=0;sprintf(cError,"%s","%");}}
| LPAR exprint RPAR {$$ = $2;}
| INTEGER {$$ = $1;}
;
exprreal:CAST_REAL LPAR exprreal RPAR {$$ = (long double)$3;}
| exprreal OP_ADD exprreal {$$ = $1 + $3;}
| exprreal OP_SUB exprreal {$$ = $1 - $3;}
| exprreal OP_MUL exprreal {$$ = $1 * $3;}
| exprreal OP_DIV exprreal {if($3)$$ = $1 / $3;else{$$=0;sprintf(cError,"%s","/");}}
| LPAR exprreal RPAR {$$ = $2;}
| DOUBLE {$$ = $1;}
| exprint OP_ADD exprreal { $$ = (double)$1 + $3;}
| exprint OP_SUB exprreal { $$ = (double)$1 - $3;}
| exprint OP_MUL exprreal { $$ = (double)$1 * $3;}
| exprint OP_DIV exprreal {if($3) $$ = (double)$1 / $3;else{$$=0;sprintf(cError,"%s","/");}}
| exprreal OP_ADD exprint {$$ = $1 + (double)$3;}
| exprreal OP_SUB exprint {$$ = $1 - (double)$3;}
| exprreal OP_MUL exprint {$$ = $1 * (double)$3;}
| exprreal OP_DIV exprint {if($3)$$ = $1 / (double)$3;else{$$=0;sprintf(cError,"%s","/");}}
| exprint OP_ADD exprint {$$ = (double)$1 + (double)$3;}
| exprint OP_SUB exprint {$$ = (double)$1 - (double)$3;}
| exprint OP_MUL exprint {$$ = (double)$1 * (double)$3;}
| exprint OP_DIV exprint{if($3)$$ = (double)$1 / (double)$3;else{$$=0;sprintf(cError,"%s","/");}}
;
%%
int yyerror(char *s)
{
printf ("%s\n",s);
return 0;
}
int ZGMCommonFourOperationFunction(const char *str, int len, char *m,char *cErr)
{
//printf("ZGM Common Four Operation Function !!!\n");
mail = m;
cError = cErr;
YY_BUFFER_STATE state = yy_scan_bytes(str, len);
yy_switch_to_buffer(state);
yyparse();
yy_delete_buffer(state);
return 0;
}
math.l文件内容
%{
#include <ctype.h>
#include"y.tab.h"
#include "stdio.h"
#include "string.h"
%}
%%
"+" {return OP_ADD;}
"-" {return OP_SUB;}
"*" {return OP_MUL;}
"/" {return OP_DIV;}
"%" {return OP_MOD;}
"(" {return LPAR;}
")" {return RPAR;}
(int|INT) {return CAST_INT;}
(real|REAL) {return CAST_REAL;}
[0-9]+ {yylval.integer = atoi(yytext); return INTEGER;}
[0-9]*\.[0-9]+ {sscanf(yytext,"%lf",&yylval.ldouble);return DOUBLE;}
"0x"[0-9a-f]+ {sscanf (yytext,"%x",&yylval.integer); return (INTEGER); }
[ \t] ;
\r {return END;}
\n { return END;}
%%
int yywrap()
{
return 1;
}
应用yacc 和 lex 命令编译他们 生成相应的 c 和 h文件。然后将c和h文件 应用 gcc 编译命令生成 对应用 c库,在应用生成的c库中的函数ZGMCommonFourOperationFunction 就可以实现各种复杂的四则运算了。 其中的应用价值,还是很广阔的,你会懂的的。