编程,用来计算用户输入的四则运算表达式的值,只含加减乘除,不含括号。
实例解析:
表达式中含有加减乘除,乘除的优先级别比加减高。
我们以键盘输入-3.12 + 2*3.5/4 + 8/2 - 3*6为例来说明算法。
式子中的2*3.5/4、8/2和3*6要先算,算完之后整个表达式将只有4个数据项,剩下的问题就很简单了。为此我们可以把整个表达式分成4部分(4块),块与块之间必定是由加减号连接的,每块中间只有乘除,没有加减。
实际上,没有必要先把每块的值都计算出来,在计算表达式的过程中,每遇到一块,可以先把这一块的结果算出来,然后与前面的计算结果进行加减运算,后面块的值可以在用到的时候再计算。
具体的计算方法是:
程序开始先定义一个变量result,并初始化为0。
从头开始处理每一块:提取一个数据,如果数据后面是乘(除),则表示该块计算未结束,继续提取第二个数据并与第一个数据进行乘(除)运算,然后再看后面的运算符,如果还是’*’或’/’,则继续提取数据并进行计算……直到遇到运算符‘+’、‘-’或空字符为止。
遇到运算符‘+’、‘-’或空字符,都表示该块的计算已经结束,可以将计算结果累加到result中了。
重复上面的方法,对每一块都作这样的处理,直到表达式结束。result就是最后的结果。
程序代码:
#include "stdio.h"
#include "stdlib.h"
float get_num(char **);
int main()
{char a[80];
int sign = 1; //对于表达式中的 ‘+’,sign = 1,对于‘-’,sign = -1
float result = 0;
char *p; //用来指向要处理的字符
clrscr();
gets(a);
p = a;
if(*p == '-') { //表达式第一个字符若是‘-’
sign = -1; //存储符号
p++;
}
while(*p != 0) { //没有遇到空字符,则循环
float m; //m用来存储某块的计算结果
m = sign*get_num(&p); //get_num执行过程中,p会向后移动
while( *p == '*' || *p == '/' ){ //该循环求解某块的结果
if( *p == '*' ) {
p++;
m *= get_num(&p);
}
else {
int div;
p++;
div = get_num(&p);
if( div == 0 ) {
printf("错误!除数为0!\n");
exit(1);
}
else
m /= div;
}
}
if(*p != '+' && *p != '-' && *p != 0){
printf("错误!遇到非法字符:%c\n", *p);
exit(0);
}
result += m; //将上面计算出的某块的结果累加到result中
if(*p == '+'){
sign = 1;
p++;
}
else if(*p == '-') {
sign = -1;
p++;
}
else //遇到空字符,退出循环
break;
}
printf("The result is %f\n", result);
getch();
return 0;
}
float get_num(char **pp) //pp指向p
{float x = 0, m = 10;
if(**pp != '.' && (**pp <'0' || **pp >'9') ) {
printf("错误!运算符后面不是一个有效的数据\n");
exit(1);
}
while(**pp >= '0' && **pp <= '9') {
x = x*10 + **pp - 48;
(*pp)++;
}
if(**pp == '.') {
(*pp)++;
while(**pp >= '0' && **pp <= '9') {
x += (**pp - 48)/m;
(*pp)++;
m *= 10;
}
}
return x;
}
实例解析:
表达式中含有加减乘除,乘除的优先级别比加减高。
我们以键盘输入-3.12 + 2*3.5/4 + 8/2 - 3*6为例来说明算法。
式子中的2*3.5/4、8/2和3*6要先算,算完之后整个表达式将只有4个数据项,剩下的问题就很简单了。为此我们可以把整个表达式分成4部分(4块),块与块之间必定是由加减号连接的,每块中间只有乘除,没有加减。
实际上,没有必要先把每块的值都计算出来,在计算表达式的过程中,每遇到一块,可以先把这一块的结果算出来,然后与前面的计算结果进行加减运算,后面块的值可以在用到的时候再计算。
具体的计算方法是:
程序开始先定义一个变量result,并初始化为0。
从头开始处理每一块:提取一个数据,如果数据后面是乘(除),则表示该块计算未结束,继续提取第二个数据并与第一个数据进行乘(除)运算,然后再看后面的运算符,如果还是’*’或’/’,则继续提取数据并进行计算……直到遇到运算符‘+’、‘-’或空字符为止。
遇到运算符‘+’、‘-’或空字符,都表示该块的计算已经结束,可以将计算结果累加到result中了。
重复上面的方法,对每一块都作这样的处理,直到表达式结束。result就是最后的结果。
程序代码:
#include "stdio.h"
#include "stdlib.h"
float get_num(char **);
int main()
{char a[80];
int sign = 1; //对于表达式中的 ‘+’,sign = 1,对于‘-’,sign = -1
float result = 0;
char *p; //用来指向要处理的字符
clrscr();
gets(a);
p = a;
if(*p == '-') { //表达式第一个字符若是‘-’
sign = -1; //存储符号
p++;
}
while(*p != 0) { //没有遇到空字符,则循环
float m; //m用来存储某块的计算结果
m = sign*get_num(&p); //get_num执行过程中,p会向后移动
while( *p == '*' || *p == '/' ){ //该循环求解某块的结果
if( *p == '*' ) {
p++;
m *= get_num(&p);
}
else {
int div;
p++;
div = get_num(&p);
if( div == 0 ) {
printf("错误!除数为0!\n");
exit(1);
}
else
m /= div;
}
}
if(*p != '+' && *p != '-' && *p != 0){
printf("错误!遇到非法字符:%c\n", *p);
exit(0);
}
result += m; //将上面计算出的某块的结果累加到result中
if(*p == '+'){
sign = 1;
p++;
}
else if(*p == '-') {
sign = -1;
p++;
}
else //遇到空字符,退出循环
break;
}
printf("The result is %f\n", result);
getch();
return 0;
}
float get_num(char **pp) //pp指向p
{float x = 0, m = 10;
if(**pp != '.' && (**pp <'0' || **pp >'9') ) {
printf("错误!运算符后面不是一个有效的数据\n");
exit(1);
}
while(**pp >= '0' && **pp <= '9') {
x = x*10 + **pp - 48;
(*pp)++;
}
if(**pp == '.') {
(*pp)++;
while(**pp >= '0' && **pp <= '9') {
x += (**pp - 48)/m;
(*pp)++;
m *= 10;
}
}
return x;
}