0

私はしばらくここにいて、同様の問題を抱えていましたが、間違った質問だと思います。少し背景を説明するために、フォームの接尾辞式を解決するCプログラムの作成を担当しました。

8 7-9 * =

私の問題は、私の教授が間違ったスタックコードを与えたということです。これは、スタックオーバーフロー(笑)エラーが常に発生していて、スタックがいっぱいになっていないためです。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

スタックに問題はありません。しかし、メインには少なくとも 2 つの問題があります。

push(&bit);

pushBitではなく、を受け入れます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 である「=」と比較しています。そのため、「!=」は常に true であり、このループを通過することはありません。

ところで、プッシュがどのように実装されているかを見ると、「スタック オーバーフロー」のチェックが is_full() 関数を使用して行われていることがわかります。is_full() は top と STACK_SIZE を比較しています。top==20 を比較しています。is_full を使用することをお勧めします。これはより抽象的であり、誰かが STACK_SIZE を変更した場合でも機能します。top==20 と top==0 のチェックを省略することもできます。これは、pop/push 関数によって既に行われている stack_underflow/stack_overflow を呼び出すだけであるためです。

于 2011-11-13T14:31:38.393 に答える
0

次の行に問題があります。

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

このscanf関数は、アイテムではなく、スキャンされたアイテムの数を返します。また、scanning for%dは、文字ではなく整数を取得しようとします。

次のようなものをもっと調べるべきだと思います:

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

これは、整数をスキャンできなくなるまで (つまり、操作を取得するまで) 整数をスタックにプッシュします。

その特定のものは通常0または1のみを返すため、これはほぼ間違いなくあなたの問題です( ASCIIを使用している場合は16進数または10進数)scanfと等しくなることはありません。場合によっては返される可能性がありますが、それでも61というは得られません。=0x3d61EOF

決して61 を返さないという事実は、単にループし続け、currentオーバーフローするまで on の値をスタックにプッシュすることを意味します。これがあなたが見ている動作です。

于 2011-11-13T14:24:28.933 に答える