练习题6
在stdin输入一行数字表达试,写代码计算这个表达式的值,可以有 '+' '-' '*' '/' 四种运算,没有优先级,也就是从左往右计算。如:
输入:3 * 4 / 2 + 9
输出:15.000000
输入:-1 + 3 - 4 * 9
输出:-18.000000
不知道voidx去干什么了,练习5的贴也没有结,现在我出一道题吧。
参考答案:
程序代码:#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <float.h>
#ifndef NULL
#define NULL ((void *)0)
#endif
#define EXP_LENGTH 102 /* 表达式的长度 */
#define SUB_EXP_DIG LDBL_DIG /* 子表达式结果的有效位数 */
#define is_operator(ch) ((ch) == '+' || (ch) == '-' || (ch) == '*' || (ch) == '/')
typedef double element_type; /* 元素值类型 */
typedef long double result_type; /* 结果值类型 */
static char exp[EXP_LENGTH];
static int exp_offset = 0;
typedef struct {
element_type left_val; /* 操作数左值 */
char op; /* 操作符 */
element_type right_val; /* 操作数右值 */
} sub_exp;
void read(void);
result_type calcing(void);
sub_exp * next_exp(sub_exp * pse);
result_type exp_val(sub_exp * pse);
void read(void) {
fgets(exp, EXP_LENGTH, stdin);
}
result_type calcing(void) {
result_type result = 0.0L;
sub_exp se = {0.0L, '\0', 0.0L}, * pse;
result = next_exp(&se) ? exp_val(&se) : se.left_val;
while(pse = next_exp(&se)) {
switch (pse->op) {
case '+':
result += pse->right_val;
break;
case '-':
result -= pse->right_val;
break;
case '*':
result *= pse->right_val;
break;
case '/':
result /= pse->right_val;
break;
}
}
return result;
}
sub_exp * next_exp(sub_exp * pse) {
int i = exp_offset, j;
char left_str[SUB_EXP_DIG + 2];
char right_str[SUB_EXP_DIG + 2];
for (j = 0; j < SUB_EXP_DIG + 1; i++)
if (isdigit(exp[i]) || (exp[i] == '.' && j))
left_str[j++] = exp[i];
else if ((exp[i] == '-' || exp[i] == '+') && !j)
left_str[j++] = exp[i];
else if (isspace(exp[i]) && exp[i] != '\n' && !j)
continue;
else
break;
left_str[j] = '\0';
pse->left_val = atof(left_str);
for (; ; i++)
if(isspace(exp[i]) && exp[i] != '\n')
continue;
else if(is_operator(exp[i]))
break;
else
return NULL;
pse->op = exp[i++];
exp_offset = i;
for (j = 0; j < SUB_EXP_DIG + 1; i++)
if (isdigit(exp[i]) || (exp[i] == '.' && j))
right_str[j++] = exp[i];
else if ((exp[i] == '-' || exp[i] == '+') && !j)
right_str[j++] = exp[i];
else if (isspace(exp[i]) && exp[i] != '\n' && !j)
continue;
else if ((exp[i] == '\n' || exp[i] == '\0') && !j)
return NULL;
else
break;
right_str[j] = '\0';
pse->right_val = atof(right_str);
return pse;
}
result_type exp_val(sub_exp * pse) {
result_type result = 0.0L;
switch (pse->op) {
case '+':
result = pse->left_val + pse->right_val;
break;
case '-':
result = pse->left_val - pse->right_val;
break;
case '*':
result = pse->left_val * pse->right_val;
break;
case '/':
result = pse->left_val / pse->right_val;
break;
}
return result;
}
int main(void) {
read();
printf("%Lf", calcing());
return 0;
}
数字之间可能会有空格,所以有些朋友的答案不对,不过参与就有分。
[ 本帖最后由 lz1091914999 于 2011-7-3 16:38 编辑 ]









