《C 语言程序设计:现代方法》第 10 章“程序结构”的第 6 题

C 语言小新一枚,求问《C 语言程序设计:现代方法》第 10 章“程序结构”的第 6 题。


题目如下:有些计算器(尤其是惠普的计算器)使用逆波兰表示法(Reverse Polish Notation, RPN)来书写数学表达式。在这一表示法中,运算符放置在操作数的后面而不是放在操作数的中间。例如,在逆波兰表示法中 1 + 2 将表示为 1 2 +,而 1 + 2 * 3将表示为 1 2 3 * +。逆波兰表达式可以很方便地用栈求值。算法从左向右读取运算符和操作数,并执行下列步骤。
(1)当遇到操作数时,将其压入栈中。
(2)当遇到运算符时,从栈中弹出它的操作数,执行运算并把结果压入栈中。


编写程序对逆波兰表达式求值。操作数都是个位的整数,运算符为 +,-,* 和 =。遇到运算 = 时,将显示栈顶项,随后清空栈并提示用户计算新的表达式。这一过程持续进行,直到用户输入一个既不是运算符也不是操作数的字符为止:

Enter an RPN expression: 1 2 3 * + =
Value of expression: 7
Enter an RPN expression: 5 8 * 4 9 - / =
Value of expression: -8
Enter an RPN expression: q

如果栈出现上溢,程序将显示消息 Expression is too complex 并终止,如果栈出现下溢(例如遇到表达式 1 2 + +),程序将显示消息 Not enough operands in expression 并终止。使用 scanf(" %c", &ch) 读取运算符和操作数。


我的代码如下

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define STACK_SIZE 100

/* external variables */
int contents[STACK_SIZE];
int top = 0;

/* prototypes */
void calculate_formula_with_polish_method(void);
void make_empty(void);
bool is_empty(void);
bool is_full(void);
void push(int i);
int pop(void);

int main(void)
{
  for (;;) {
    calculate_formula_with_polish_method();
  }

  return 0;
}

/************************************************************
 * calculate_formula_with_polish_method: calculate the      *
 *                                       value of formula   *
 *                                       using Polish       *
 *                                       method.            *
 ************************************************************/
void calculate_formula_with_polish_method(void)
{
  char ch;
  int input, first, second;

  printf("Enter an RPN expression: ");

  do {
    scanf(" %c", &ch);
    if (ch >= '0' && ch <= '9') {
      input = ch - '0';
      scanf("%c", &ch);
      while (ch >= '0' && ch <= '9') {
        input = input * 10 + ch - '0';
        scanf("%c", &ch);
      }
      push(input);
      continue;
    }
    else if (ch == '+') push(pop() + pop());
    else if (ch == '*') push(pop() * pop());
    else if (ch == '-') {
      first   = pop();
      second  = pop();
      push(first - second);
    } else if (ch == '/') {
      first   = pop();
      second  = pop();
      push(first / second);
    } else if (ch == '=') {
      printf("Value of expression: %d", pop());
      make_empty();
      break;
    } else
      exit(EXIT_SUCCESS);
  } while (1);
}

void make_empty(void)
{
  top = 0;
}

bool is_empty(void)
{
  return top == 0;
}

bool is_full(void)
{
  return top == STACK_SIZE;
}

void push(int i)
{
  if (is_full()) {
    printf("Expression is too complex\n");
    exit(EXIT_FAILURE);
  }
  else
    contents[top++] = i;
}

int pop(void)
{
  if (is_empty())
    printf("Not enoungh operands in expression\n");
    exit(EXIT_FAILURE);
  return contents [--top];
}

代码的问题在哪呢?这是代码运行的结果:

img

【以下回答由 GPT 生成】

问题描述: 请问《C 语言程序设计:现代方法》第 10 章“程序结构”的第 6 题是什么?

问题补充: 在逆波兰表示法中,运算符放置在操作数的后面而不是放在操作数的中间。编写程序对逆波兰表达式求值。操作数都是个位的整数,运算符为 +、-、* 和 =。遇到运算 = 时,将显示栈顶项,随后清空栈并提示用户计算新的表达式。如果栈出现上溢,程序将显示消息 "Expression is too complex" 并终止。如果栈出现下溢,程序将显示消息 "Not enough operands in expression" 并终止。使用 scanf(" %c", &ch) 读取运算符和操作数。

以下是您提供的代码(已稍作调整):

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define STACK_SIZE 100

int contents[STACK_SIZE];
int top = 0;

void calculate_formula_with_polish_method(void);
void make_empty(void);
bool is_empty(void);
bool is_full(void);
void push(int i);
int pop(void);

int main(void)
{
  for (;;) {
    calculate_formula_with_polish_method();
    make_empty();
  }
  return 0;
}

void calculate_formula_with_polish_method(void)
{
  char ch;
  int op1, op2;

  printf("Enter an RPN expression: ");
  for (;;) {
    scanf(" %c", &ch);
    if (ch >= '0' && ch <= '9') {
      push(ch - '0');
    } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
      op2 = pop();
      op1 = pop();
      switch (ch) {
        case '+': push(op1 + op2); break;
        case '-': push(op1 - op2); break;
        case '*': push(op1 * op2); break;
        case '/': push(op1 / op2); break;
      }
    } else if (ch == '=') {
      printf("Value of expression: %d\n", pop());
      return;
    } else {
      break;
    }
  }
  printf("Expression is too complex\n");
  exit(EXIT_FAILURE);
}

void make_empty(void)
{
  top = 0;
}

bool is_empty(void)
{
  return top == 0;
}

bool is_full(void)
{
  return top == STACK_SIZE;
}

void push(int i)
{
  if (is_full()) {
    printf("Expression is too complex\n");
    exit(EXIT_FAILURE);
  } else {
    contents[top++] = i;
  }
}

int pop(void)
{
  if (is_empty()) {
    printf("Not enough operands in expression\n");
    exit(EXIT_FAILURE);
  } else {
    return contents[--top];
  }
}

请您帮我优化一下问题描述,使得 chatgpt 能够更好地理解我的问题并给出更准确的答案。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^