0

我在这里待了一段时间,遇到了类似的问题,但我认为问题是错误的。为了提供一些背景知识,我的任务是创建一个 C 程序来解决表单中的后缀表达式

8 7 - 9 * =

我认为我的问题是,我的教授给出了一些不正确的堆栈代码。我这样说是因为我经常收到堆栈溢出(lol)错误,而且我的堆栈还远未满。如果有帮助,我正在使用 Visual Studio 2005。这是我的代码:

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

    #define STACK_SIZE 20

    typedef int Bit;

    Bit contents[STACK_SIZE];
    int top = 0;

    void make_empty(void);
    int is_empty(void);
    int is_full(void);
    void push(Bit i);
    int pop(void);
    void stack_overflow(void);
    void stack_underflow(void);

    int main(void) {
      Bit bit;
      char operation;
      int operand;
      Bit current;
      int result;

        while(scanf("%d",&current)!= '=')
        {
            push(current);
        }

        scanf("%c", &operation);
        while(operation != '=')
        {
            scanf("%d", &operand);
            printf("%d\n",top);
            //Pushes any number into the stack
            if(operand==1||operand==2||operand==3||operand==4||operand==5||operand==6||operand==7||operand==8||operand==9||operand==0)
            {
                printf("entered number loop\n");
                bit = operand;
                if(top==20)
                {
                    stack_overflow();
                }
                push(&bit);
            }

            //Performs subtraction operation
            else if(operation == '-')
            {
                printf("entered minus loop\n");
                if(top==1)
                {
                    stack_underflow();
                }

                result = pop() - pop();

                bit = result;

                if(top==20)
                {
                    stack_overflow();
                }

                push(&bit);
            }

            //Performs addition operation
            else if(operation == '+')
            {
                if(top==1)
                {
                    stack_underflow();
                }

                result = pop() + pop();
                bit = result;

                if(top==20)
                {
                    stack_overflow();
                }

                push(&bit);
            }

            //Performs multiplication operation
            else if(operation == '*')
            {
                if(top==1)
                {
                    stack_underflow();
                }

                result = pop() * pop();
                bit = result;

                if(top==20)
                {
                    stack_overflow();
                }

                push(&bit);
            }

            //Performs division operation
            else if(operation == '/')
            {
                if(top==1)
                {
                    stack_underflow();
                }

                result = pop() / pop();
                bit = result;

                if(top==20)
                {
                    stack_overflow();
                }

                push(&bit);
            }

            else if(operation == '=')
            {
                if(top==0)
                {
                    stack_underflow();
                }

                printf("%d\n",pop());
                break;
            }
        }
  return 0;
}

void make_empty(void) {
  top = 0;
}

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

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

void push(Bit i) {
  if (is_full())
    stack_overflow();
  else
    contents[top++] = i;
}

int pop(void) {
  if (is_empty())
    stack_underflow();
  else
    return contents[top--];
}

void stack_overflow(void) {
  printf("Error: stack overflow!\n");
  exit(EXIT_FAILURE);
}

void stack_underflow(void) {
  printf("Error: stack underflow!\n");
  exit(EXIT_FAILURE);
}

现在我意识到我的代码现在有点野蛮,为此我深表歉意。话虽如此,任何帮助或意见都将不胜感激,并提前感谢大家。


好的,所以在考虑了所有因素之后,我想我已经接近了。一切都正确进入堆栈,一切都被正确读取。但是,我的新实现包括将所有内容都设为字符,然后在需要使用整数时对其进行转换。这是我的源代码:

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

#define STACK_SIZE 20

typedef int Bit;

char contents[STACK_SIZE];
int top = 0;

void make_empty(void);
int is_empty(void);
int is_full(void);
void push(char i);
char pop(void);
void stack_overflow(void);
void stack_underflow(void);

int main(void) {
    char current = 'a';
    char result = 'a';
    char operation = 'a';
    char char1;
    char char2;
    int number1;
    int number2;

    scanf("%c", &current);
    //While program successfully scanned a number
    while(current != '=')
    {

        //Performs subtraction operation
        if(current == '-')
        {
            printf("entered if 2\n");
            char1 = pop();
            number1 = char1 - '0';
            printf("%d\n", number1);
            char2 = pop();
            number2 = char2 - '0';
            printf("%d\n", number2);
            result = number1 - number2;

            push(result);
        }

        //Performs addition operation
        else if(current == '+')
        {
            printf("entered if 2\n");
            char1 = pop();
            number1 = char1 - '0';
            printf("%d\n", number1);
            char2 = pop();
            number2 = char2 - '0';
            printf("%d\n", number2);
            result = number1 + number2;

            push(result);
        }

        //Performs multiplication operation
        else if(current == '*')
        {
            printf("entered if 2\n");
            char1 = pop();
            number1 = char1 - '0';
            printf("%d\n", number1);
            char2 = pop();
            number2 = char2 - '0';
            printf("%d\n", number2);
            result = number1 * number2;

            push(result);
        }

        //Performs division operation
        else if(current == '/')
        {
            printf("entered if 2\n");
            char1 = pop();
            number1 = char1 - '0';
            printf("%d\n", number1);
            char2 = pop();
            number2 = char2 - '0';
            printf("%d\n", number2);
            result = number1 / number2;

            push(result);
        }

        else
        {
            push(current);
            printf("%c\n", current);
        }

        scanf(" %c", &current);
    }   

    //Prints result
    printf("%c\n",pop());

    return 0;
}

void make_empty(void) {
  top = 0;
}

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

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

void push(char i) {
  if (is_full())
    stack_overflow();
  else
    contents[top++] = i;
}

char pop(void) {
  if (is_empty())
    stack_underflow();
  else
    return contents[top--];
}

void stack_overflow(void) {
  printf("Error: stack overflow!\n");
  exit(EXIT_FAILURE);
}

void stack_underflow(void) {
  printf("Error: stack underflow!\n");
  exit(EXIT_FAILURE);
}

请记住,我一直在玩弄它,所以有随机的 printfs 和无用的变量都用于调试目的。每当我运行它时(例如输入 3 5 + =),我得到:

在此处输入图像描述

所以再次,请原谅我的一些乱七八糟的代码,因为我对 C 很陌生,但任何帮助都会很棒!

4

3 回答 3

1

我没有看到堆栈有任何问题。但是您的主要问题至少有两个问题。

push(&bit);

push接受 a Bit,而不是 a Bit *。你应该在这里得到一个警告,你可能已经忽略了。不要忽略警告。

while(scanf("%d",&current)!= '=')

这绝对是错误的。scanf返回成功输入的数量。

operand==1||operand==2||operand==3||operand==4||operand==5||operand==6||operand==7||operand==8||operand==9||operand==0

虽然这不是错误,但为什么要这样写?您可以轻松替换为:

operand >= 0 && operand <= 9

而且可能还有很多问题。

于 2011-11-13T14:30:39.060 回答
1

这是一个无限循环:

while(scanf("%d",&current)!= '=') { push(current); }

scanf 返回成功读取的字段数。在您的情况下,这可以是 0 或 1。您将其与 ASCII 61 的 '=' 进行比较。因此 '"!=" 始终为真,并且您永远不会越过这个循环。

顺便说一句,如果您查看 push 是如何实现的,您会发现“堆栈溢出”的检查是使用 is_full() 函数完成的。is_full() 将 top 与 STACK_SIZE 进行比较。您正在比较 top==20。你最好使用 is_full。这更抽象,即使有人更改了 STACK_SIZE 也可以工作。您甚至可以省略对 top==20 和 top==0 的检查,因为您唯一要做的就是调用 stack_underflow/stack_overflow,这已由 pop/push 函数完成。

于 2011-11-13T14:31:38.393 回答
0

您对以下行有问题:

while(scanf("%d",&current)!= '=')

scanf函数返回扫描的项目数,而不是项目。并且扫描%d将尝试获取一个整数,而不是一个字符。

我认为您应该更多地研究以下内容:

while (scanf("%d",&current) == 1)
    push(current);

这会将整数推入堆栈,直到它无法再扫描一个(即,您得到一个操作)。

这几乎肯定是您的问题,因为该特定scanf值通常只会返回 0 或 1,这意味着它永远不会等于(如果您使用的是 ASCII =,则为十六进制0x3d或十进制)。在某些情况下61可能会返回,但仍然不会为您提供 61 的值。EOF

它永远不会返回 61的事实意味着它只会继续循环,将 on 的值推current送到您的堆栈直到它溢出,这就是您所看到的行为。

于 2011-11-13T14:24:28.933 回答