一个存在一些问题的程序
这个程序的思路:先举个例子:2*((2+2)*2))
首先,两个数之间必定会有运算符,其次,一个式子的最左端要么是一个数字,要么是一个左括号。
由于这个程序只涉及加减乘除,故只需要获得两个运算符就可以对其进行化简。
如:2*3+4-->6+4;2*3*4-->6*4;2+3*4-->2+12;
假设输入的式子是正确的
输入一个式子,先读一个数,若失败,那么第一个符号必定是左括号,并且这个左括号和与其匹配的右括号之间的内容也构成一个式子,因此,遇到左括号便可递归调用求解式子的函数。
若成功,继续读取第一个运算符,第二个数字,第二个运算符,第三个数字,读取三个数字之后便可化简,然后继续读第二个运算符,第三个数字,再化简,期间若遇到右括号或换行符,说明这一层式子计算完成,返回主调函数。
但是当输入的式子在格式上有问题时,就会出现各种尴尬的局面
程序代码:#include <stdio.h>
#include <math.h>
#include <ctype.h>
#define LENGTH 3
#define WIDTH 2
int FLAG; //FALG == 1 说明式子格式正确,FLAG == 0 说明式子格式错误
const char PRIORITY[LENGTH][WIDTH] = { {'+', '-'}, {'*', '/'}, {'(', ')'} }; //定义运算符优先级
size_t priority(char); //确定运算符优先级等级
double operation(double, char, double); //返回两个值运算后的结果
void simplificat(double *, char *, double *, char *, double *); //化简式子
char read_operator(void); //读取下一个运算符
double read_num(void); //读取下一个数字
double formula(void); //求解式子的值
int main(void)
{
while (FLAG = 1)
{
double result = formula();
if (FLAG)
printf("\nresult = %g\n\n\n", result);
else
{
printf("\n格式错误\n\n\n");
}
}
return 0;
}
size_t priority(char operator_) //确定运算符优先级等级
{
for (size_t i = 0; i < LENGTH; i++)
for (size_t j = 0; j < WIDTH; j++)
if (operator_ == PRIORITY[i][j])
return i;
if (operator_ != '\n')
FLAG = 0;
return LENGTH;
}
double operation(double num_1, char operator_, double num_2)
{
switch (operator_)
{
case '+': num_1 += num_2; break;
case '-': num_1 -= num_2; break;
case '*': num_1 *= num_2; break;
case '/':
if (fabs(num_2) < 1e-6)
FLAG = 0;
else
num_1 /= num_2;
break;
}
return num_1;
}
void simplificat(double *num_1, char *operator_1, double *num_2, char *operator_2, double *num_3)
{
if (priority(*operator_1) >= priority(*operator_2))
{
*num_1 = operation(*num_1, *operator_1, *num_2);
*operator_1 = *operator_2;
*num_2 = *num_3;
}
else
*num_2 = operation(*num_2, *operator_2, *num_3);
}
char read_operator(void)
{
char operator_;
while (isspace(operator_ = getchar()) && operator_ != '\n');//跳过空白符
return operator_;
}
double read_num(void)
{
double num = 0;
if (!scanf("%lf", &num))
{
if (getchar() == '(')//如果是左括号,那么计算括号内的值
num = formula();
else
FLAG = 0;
}
return num;
}
double formula(void)
{
double num_1 = 0, num_2 = 0, num_3;
char operator_12 = 0, operator_23 = 0;
if (FLAG)
num_1 = read_num();
if (FLAG)
operator_12 = read_operator();
if (!FLAG)
return 0;
if (operator_12 == ')' || operator_12 == '\n')
return num_1;
if (FLAG)
num_2 = read_num();
while (1)
{
if (FLAG)
operator_23 = read_operator();
if (!FLAG)
return 0;
if (operator_23 == ')' || operator_23 == '\n')
return operation(num_1, operator_12, num_2);
if (FLAG)
num_3 = read_num();
simplificat(&num_1, &operator_12, &num_2, &operator_23, &num_3);
}
}




