while (fgets(exp, sizeof(exp), stdin))
时间: 2023-11-25 10:05:34 浏览: 61
这段代码使用了 fgets 函数从标准输入流中读取一行字符串,保存到字符数组 exp 中。sizeof(exp) 表示 exp 数组的总大小,fgets 函数会读取指定大小的数据,遇到换行符或者读取到了指定大小的数据就会停止读取。这个代码段的意思是,不断从标准输入流中读取字符串,直到读取到 EOF(文件结束符)。
相关问题
用户从键盘输入一个算术表达式,数字都是十进制整型(必须支持负数),运算符支持+-*/()。编写源程序中的 double deal_exp (char *exp) 函数,对这个算术表达式求值,返回结果。
好的,我来解答您的问题。
首先,您需要将中缀表达式转换为后缀表达式。这可以通过使用栈来实现。具体步骤如下:
1. 创建一个运算符栈和一个结果栈。
2. 从左到右遍历表达式中的每个字符。
3. 如果字符是数字,则将它压入结果栈。
4. 如果字符是左括号,则将其压入运算符栈。
5. 如果字符是右括号,则将运算符栈中的运算符弹出并压入结果栈,直到遇到左括号为止。
6. 如果字符是运算符,则将其压入运算符栈。但在压入之前,需要先将运算符栈中优先级大于或等于该运算符的运算符弹出并压入结果栈。
7. 最后,将运算符栈中剩余的运算符依次弹出并压入结果栈。
完成后,您会得到一个后缀表达式。接下来,您可以使用另一个栈来计算后缀表达式的值。具体步骤如下:
1. 创建一个栈。
2. 从左到右遍历后缀表达式中的每个字符。
3. 如果字符是数字,则将其压入栈。
4. 如果字符是运算符,则从栈中弹出两个操作数,并根据运算符进行计算。将计算结果压入栈。
5. 最后,栈中只剩下一个元素,即为最终结果。
下面是示例代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct _stack {
int top;
int capacity;
double *data;
} Stack;
Stack* create_stack(int capacity) {
Stack *stack = malloc(sizeof(Stack));
stack->top = -1;
stack->capacity = capacity;
stack->data = malloc(sizeof(double) * capacity);
return stack;
}
void push(Stack *stack, double value) {
if (stack->top == stack->capacity - 1) {
printf("Stack overflow!\n");
return;
}
stack->top++;
stack->data[stack->top] = value;
}
double pop(Stack *stack) {
if (stack->top == -1) {
printf("Stack underflow!\n");
return 0.0;
}
double value = stack->data[stack->top];
stack->top--;
return value;
}
double peek(Stack *stack) {
if (stack->top == -1) {
printf("Stack underflow!\n");
return 0.0;
}
return stack->data[stack->top];
}
int is_empty(Stack *stack) {
return stack->top == -1;
}
int is_operator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
int precedence(char c) {
if (c == '*' || c == '/') {
return 2;
} else if (c == '+' || c == '-') {
return 1;
} else {
return 0;
}
}
double evaluate(char *exp) {
Stack *operator_stack = create_stack(strlen(exp));
Stack *result_stack = create_stack(strlen(exp));
int i = 0;
while (exp[i] != '\0') {
if (isdigit(exp[i]) || (exp[i] == '-' && i == 0)) {
char *endptr;
double value = strtod(&exp[i], &endptr);
push(result_stack, value);
i = endptr - exp;
} else if (exp[i] == '(') {
push(operator_stack, exp[i]);
i++;
} else if (exp[i] == ')') {
while (!is_empty(operator_stack) && peek(operator_stack) != '(') {
char op = pop(operator_stack);
double operand2 = pop(result_stack);
double operand1 = pop(result_stack);
double result;
switch (op) {
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
}
push(result_stack, result);
}
pop(operator_stack);
i++;
} else if (is_operator(exp[i])) {
while (!is_empty(operator_stack) && precedence(peek(operator_stack)) >= precedence(exp[i])) {
char op = pop(operator_stack);
double operand2 = pop(result_stack);
double operand1 = pop(result_stack);
double result;
switch (op) {
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
}
push(result_stack, result);
}
push(operator_stack, exp[i]);
i++;
} else {
printf("Invalid character: %c\n", exp[i]);
return 0.0;
}
}
while (!is_empty(operator_stack)) {
char op = pop(operator_stack);
double operand2 = pop(result_stack);
double operand1 = pop(result_stack);
double result;
switch (op) {
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '*':
result = operand1 * operand2;
break;
case '/':
result = operand1 / operand2;
break;
}
push(result_stack, result);
}
double result = pop(result_stack);
free(operator_stack->data);
free(operator_stack);
free(result_stack->data);
free(result_stack);
return result;
}
int main() {
char exp[100];
printf("Enter an arithmetic expression: ");
fgets(exp, 100, stdin);
printf("Result: %.2f\n", evaluate(exp));
return 0;
}
```
在这个示例代码中,我们使用了两个栈来实现中缀表达式到后缀表达式的转换和后缀表达式的计算。其中,is_empty()、peek()、push()、pop() 函数实现了栈的基本操作。evaluate() 函数是主函数,它接受一个中缀表达式作为参数,并返回计算结果。
在该函数中,我们首先创建了一个运算符栈和一个结果栈。然后,我们从左到右遍历中缀表达式中的每个字符,并根据字符的类型进行不同的操作。最后,我们计算结果栈中的结果并返回计算结果。
这就是一个简单的中缀表达式求值程序。希望对您有所帮助。
用c语言写算术表达式求值程序。演示程序和源程序已给出。用户从键盘输入一个算术表达式,数字都是十进制整型(必须支持负数),运算符支持+-*/()。 编写源程序中的 double deal_exp (char *exp) 函数,对这个算术表达式求值,返回结果。不限制方法,你可以用“原始”的多遍扫描字符串,也可以用先进一点的栈
以下是用栈实现算术表达式求值的 C 语言程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define STACK_SIZE 100
typedef struct {
int top;
int data[STACK_SIZE];
} Stack;
void init_stack(Stack *s) {
s->top = -1;
}
void push(Stack *s, int item) {
if (s->top == STACK_SIZE - 1) {
printf("Stack overflow\n");
exit(EXIT_FAILURE);
}
s->data[++s->top] = item;
}
int pop(Stack *s) {
if (s->top == -1) {
printf("Stack underflow\n");
exit(EXIT_FAILURE);
}
return s->data[s->top--];
}
int peek(Stack *s) {
if (s->top == -1) {
printf("Stack underflow\n");
exit(EXIT_FAILURE);
}
return s->data[s->top];
}
int is_empty(Stack *s) {
return (s->top == -1);
}
int precedence(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
double evaluate_expression(char *exp) {
Stack operand_stack;
Stack operator_stack;
char *endptr;
char *p = exp;
init_stack(&operand_stack);
init_stack(&operator_stack);
while (*p != '\0') {
if (isspace(*p)) {
p++;
} else if (isdigit(*p)) {
int operand = strtol(p, &endptr, 10);
push(&operand_stack, operand);
p = endptr;
} else if (*p == '(') {
push(&operator_stack, '(');
p++;
} else if (*p == ')') {
while (peek(&operator_stack) != '(') {
char op = pop(&operator_stack);
int operand2 = pop(&operand_stack);
int operand1 = pop(&operand_stack);
switch (op) {
case '+':
push(&operand_stack, operand1 + operand2);
break;
case '-':
push(&operand_stack, operand1 - operand2);
break;
case '*':
push(&operand_stack, operand1 * operand2);
break;
case '/':
push(&operand_stack, operand1 / operand2);
break;
}
}
pop(&operator_stack);
p++;
} else {
while (!is_empty(&operator_stack) && peek(&operator_stack) != '(' && precedence(*p) <= precedence(peek(&operator_stack))) {
char op = pop(&operator_stack);
int operand2 = pop(&operand_stack);
int operand1 = pop(&operand_stack);
switch (op) {
case '+':
push(&operand_stack, operand1 + operand2);
break;
case '-':
push(&operand_stack, operand1 - operand2);
break;
case '*':
push(&operand_stack, operand1 * operand2);
break;
case '/':
push(&operand_stack, operand1 / operand2);
break;
}
}
push(&operator_stack, *p);
p++;
}
}
while (!is_empty(&operator_stack)) {
char op = pop(&operator_stack);
int operand2 = pop(&operand_stack);
int operand1 = pop(&operand_stack);
switch (op) {
case '+':
push(&operand_stack, operand1 + operand2);
break;
case '-':
push(&operand_stack, operand1 - operand2);
break;
case '*':
push(&operand_stack, operand1 * operand2);
break;
case '/':
push(&operand_stack, operand1 / operand2);
break;
}
}
return (double) peek(&operand_stack);
}
int main() {
char exp[100];
printf("Enter an arithmetic expression: ");
fgets(exp, sizeof(exp), stdin);
double result = evaluate_expression(exp);
printf("Result: %g\n", result);
return 0;
}
```
其中,`deal_exp` 函数被重命名为 `evaluate_expression`,并返回了 `double` 类型的结果。该函数用两个栈来实现算术表达式求值。一个栈(称为“操作数栈”)用于存储操作数,另一个栈(称为“运算符栈”)用于存储运算符。算法的基本思路是,从左到右扫描表达式的每个字符,如果是空格则跳过,如果是数字则将其转换成整数并压入操作数栈,如果是左括号则将其压入运算符栈,如果是右括号则弹出运算符栈中的运算符和操作数栈中的两个操作数,进行计算,并将计算结果压入操作数栈。如果是其他运算符,则不断弹出运算符栈中优先级大于等于该运算符的运算符,并从操作数栈中弹出两个操作数进行计算,然后将计算结果压入操作数栈。最后,当扫描完整个表达式后,将运算符栈中剩余的运算符和操作数栈中的操作数依次弹出进行计算即可。
阅读全文