简体   繁体   English

C中的简单堆栈程序

[英]Simple stack program in C

I am in an OS class and I have to write a simple stack program (the main function just determines what the user is asking you to do). 我在OS类中,我必须编写一个简单的堆栈程序(main函数只是确定用户要求你做什么)。 If this were not required to be in C, I would have had this done ages ago, but because I am not very good at C coding, it has "a bug"... The bug so far is that it just continues to "pop" the same value off. 如果这不是必须在C中,我会在很久以前完成这个,但因为我不擅长C编码,它有“一个错误”......到目前为止的错误是它只是继续“流行“相同的价值。 (It's not actually popping anything off). (它实际上并没有弹出任何东西)。 I think it's because I don't understand how structures and pointers really work. 我认为这是因为我不明白结构和指针是如何工作的。 Or is it a not so obvious coding mistake? 或者这是一个不那么明显的编码错误?

#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;
}

first should be a pointer. 首先应该是一个指针。 change it to struct node *first ; 首先将其更改为struct node * ;

in main initialize first=NULL ; 在main initialize first = NULL ;

change you push/pop operations as below, 改变你的推/弹操作如下,

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);
}

The problem is that first is a single global node , and it's the only node you ever have (aside from a temporary local node inside your call to push ). 问题是, first是一个单一的全局node ,它是您拥有的唯一node (除了您的push调用中的临时本地node )。

This line: 这一行:

    first = newNode;

just copies the contents of newNode over into first ; 只需将newNode的内容复制到first ; and since newNode.next is pointing to first , this means that now first.next is pointing to first , so you have a single-element circular linked list. 并且由于newNode.next指向first ,这意味着现在first.next指向first ,因此您有一个单元素循环链表。

Similarly, this line: 同样,这一行:

    first = *(first.next);

just copies the contents of *(first.next) over into first ; 只需将*(first.next)的内容复制到first ; which is a no-op, since (due to the above), *(first.next) is first . 这是一个无操作,因为(由于上述原因), *(first.next) first

To solve this problem, you actually need to dynamically create nodes, using malloc (and free ). 要解决此问题,您实际上需要使用malloc (和free )动态创建节点。 And your global first variable should be a pointer — a node * — that always points to the top element of the stack. 而你的全局first变量应该是一个指针 - 一个node * - 它总是指向堆栈的顶部元素。 (Better yet, your push and pop functions should take first as an argument, rather than having this as a global variable. There's no need for these functions to only allow a single stack to exist.) (更好的是,你的pushpop函数应该first作为参数,而不是将它作为一个全局变量。这些函数不需要只允许单个堆栈存在。)

What's the value of &first ? &first的价值是什么? Hint, it's always the same since first is statically allocated. 提示,它始终是相同的,因为first是静态分配。 Even if you change the contents of the structure, the address won't change. 即使您更改结构的内容,地址也不会更改。 This might tell you why there's a bug in push . 这可能会告诉您为什么push存在错误。 You'll need to use malloc and free if you are going to have a structure of varying size. 如果要使用不同大小的结构,则需要使用mallocfree

When you have to manage memory yourself, as C requires you to do, you need to know the difference between areas of memory known as the stack and the heap. 当你必须自己管理内存时,正如C要求你做的那样,你需要知道被称为堆栈的内存区域和堆之间的区别。 (This "stack" is slightly different than the data structure you are creating in your program.) (此“堆栈”与您在程序中创建的数据结构略有不同。)

Your push() function is creating a new node on the stack; 你的push()函数正在堆栈上创建一个新节点; when the function exits the stack is popped and the memory occupied by your new node is up for grabs. 当函数退出堆栈时会弹出,并且新节点占用的内存可用于获取。 The fact that you see values you entered is due to the fact that your program is very simple. 您看到输入的值的事实是由于您的程序非常简单。 If it was calling other functions that did other things they would almost certainly overwrite that part of the stack and when you called pop() , you would see garbage. 如果它正在调用执行其他操作的其他函数,那么它们几乎肯定会覆盖堆栈的那一部分,当你调用pop() ,你会看到垃圾。

As others have indicated, you need to use the functions malloc() and free() , which give you memory from the heap instead of the stack. 正如其他人指出的那样,你需要使用函数malloc()free() ,它们从堆而不是堆栈中提供内存。

If you want to make a stack with a linked list, make first variable as a pointer. 如果要使用链表创建堆栈,请将first变量作为指针。 then, when you push a new node to the stack, make a new node by allocating on the heap memory by malloc(). 然后,当您将新节点推送到堆栈时,通过malloc()分配堆内存来创建一个新节点。 I know that you intend to use it to point to the top of the stack. 我知道你打算用它来指向堆栈的顶部。 right? 对?

In your code, first variable is overwritten by a new node since it is not a pointer variable but a value variable. 在您的代码中, first变量被新节点覆盖,因为它不是指针变量而是值变量。 That makes a result to lost a top node of the stack. 这会导致丢失堆栈的顶级节点。

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);
}
#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);

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM