3

私は OS クラスにいて、単純なスタック プログラムを作成する必要があります (メイン関数は、ユーザーが何を求めているかを判断するだけです)。これが C である必要がなければ、何年も前にこれを行っていたでしょうが、私は C コーディングがあまり得意ではないため、「バグ」があります...これまでのバグは、「 pop」と同じ値をオフにします。(実際には何も飛び出していません)。構造体とポインターが実際にどのように機能するかを理解していないためだと思います。それとも、それほど明白ではないコーディングの間違いですか?

#include <stdio.h>

struct node {
    int data;
    struct node *next;
    struct node *prev;
} first;

void push(int);
void pop();

int main(void)
{
    int command = 0;

    while (command != 3)
    {
        printf("Enter your choice:\n1) Push integer\n2) Pop Integer\n3) Quit.\n");
        scanf("%d",&command);
        if (command == 1)
        {
            // push
            int num;
            scanf("%d",&num);
            push(num);
        }
        else
        {
            if (command == 2)
            {
                pop();
            }
            else
            {
                if (command != 3)
                {
                    printf("Command not understood.\n");
                }
            }
        }
    }

    return 0;
}

void push (int x)
{
    struct node newNode;
    newNode.data = x;
    newNode.prev = NULL;
    newNode.next = &first;
    first = newNode;
    printf("%d was pushed onto the stack.\n", first.data);
}

void pop()
{
    if (first.data == '\0')
    {
        printf("Error: Stack Empty.\n");
        return; 
    }
    printf("%d was popped off the stack.\n", first.data);
    first = *(first.next);
    first.prev = NULL;
}
4

7 に答える 7

5

最初はポインタでなければなりません。それをstruct node *firstに変更します。

メインで初期化最初= NULL ;

プッシュ/ポップ操作を次のように変更します。

void push (int x)
{
    struct node *newNode;// It should be a pointer
newNode = (struct node *)malloc(sizeof(struct node));
    newNode->data = x;
    //newNode.prev = NULL; // You don't need this
    newNode->next = first;
    first = newNode;
    printf("%d was pushed onto the stack.\n", first->data);
}

void pop()
{
struct node *prevPtr;
    //if (first.data == '\0')
    if (first == NULL) // check if stack is empty
    {
        printf("Error: Stack Empty.\n");
        return; 
    }

    printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
    first = first->next;

free(prevPtr);
}
于 2013-09-25T02:32:27.050 に答える
4

問題は、それfirstが単一の globalnodeであり、それが唯一のものであることです (への呼び出し内nodeの一時的なローカルを除いて)。nodepush

この行:

    first = newNode;

newNodeover の内容をfirst;にコピーするだけです。newNode.nextが を指しているので、これはが を指しているfirstことを意味するので、単一要素の循環リンク リストができます。first.nextfirst

同様に、この行:

    first = *(first.next);

*(first.next)over の内容をfirst;にコピーするだけです。(上記の理由により) が であるため、これはノーオペレーション*(first.next) です first

この問題を解決するには、malloc(およびfree) を使用して実際にノードを動的に作成する必要があります。また、グローバル変数は、常にスタックの最上位要素をfirst指すポインタ (a) である必要があります。node *(さらに良いことに、これをグローバル変数として持つのではなく、関数と引数として取る必要があります。これらの関数が単一のスタックの存在のみを許可する必要はありませんpushpop)first

于 2013-09-25T02:17:50.600 に答える
2

の値は&first? firstヒント、静的に割り当てられるため、常に同じです。構造体の内容を変更しても、アドレスは変わりません。これにより、 にバグがある理由がわかりますpush。さまざまなサイズの構造を作成する場合はmalloc、 andを使用する必要があります。free

于 2013-09-25T02:16:24.633 に答える
1

C で要求されるように、自分でメモリを管理する必要がある場合は、スタックとヒープとして知られるメモリ領域の違いを知る必要があります。(この「スタック」は、プログラムで作成しているデータ構造とは少し異なります。)

関数push()はスタック上に新しいノードを作成しています。関数が終了すると、スタックがポップされ、新しいノードが占有していたメモリが解放されます。入力した値が表示されるのは、プログラムが非常に単純だからです。他のことを行う他の関数を呼び出していた場合、ほぼ確実にスタックのその部分を上書きし、呼び出したときにpop()ガベージが表示されます。

他の人が示したように、スタックではなくヒープからメモリを提供する関数malloc()とを使用する必要があります。free()

于 2013-09-25T02:21:37.290 に答える
1
void pop()
{
struct node *prevPtr;
//if (first.data == '\0')
if (first == NULL)
{
    printf("Error: Stack Empty.\n");
    return; 
}

printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
first = first->next;

free(prevPtr);
}
于 2013-09-25T02:34:23.927 に答える
1

連結リストでスタックを作りたい場合は、first変数をポインタにしてください。次に、新しいノードをスタックにプッシュするときに、malloc() によってヒープ メモリに割り当てて新しいノードを作成します。スタックの一番上を指すためにそれを使用するつもりであることは知っています。右?

コードでは、first変数はポインター変数ではなく値変数であるため、新しいノードによって上書きされます。これにより、スタックの最上位ノードが失われます。

于 2013-09-25T02:25:51.043 に答える
-2
#include<stdio.h>

# define max 10

int stack[max],top=-1,size=0;

void push()

{

     if(top==(max-1))

     {

         printf("stack full\n");

     }

     else

     {

    top++;

    printf("enter the value which you want to insert\n");

    scanf("%d",&stack[top]);

     }

}

void pop()

{

int str;

if(top==-1)

        {

         printf("stack empty\n");

     }

     else

        {


    str=stack[top];

     top--;

    printf("the removed element is %d\n",str);

        }

}

void display()

{

 int i;

    for(i=0;i<top;i++)

    {

        printf("%d\n",stack[i]);

    }

}

void main()

{ 

int enter,x;

    do

    {

        printf("enter 1 for push the element in the array\n");

        printf("enter 2 for pop the element in the array\n");

        printf("enter 3 for display the element in the array\n");

        scanf("%d",&enter);

        switch(enter)

        {

        case 1:push();

        break;

        case 2:pop();

        break;

        case 3:display();

        break;

    default:

        printf("invalid syntax");

        }


         printf("for continue press 0\n");

        scanf("%d",&x);

    }

while(x==0);

}
于 2018-09-03T09:40:59.680 に答える