【问题标题】:Simple stack program in CC中的简单堆栈程序
【发布时间】:2013-09-30 11:07:50
【问题描述】:

我在一个操作系统类中,我必须编写一个简单的堆栈程序(主函数只是确定用户要求你做什么)。如果这不需要在 C 中,我会在很久以前就这样做了,但是因为我不太擅长 C 编码,所以它有一个“错误”......到目前为止的错误是它只是继续“弹出”相同的值关闭。 (它实际上并没有弹出任何东西)。我认为这是因为我不明白结构和指针是如何工作的。还是不是很明显的编码错误?

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

【问题讨论】:

    标签: c stack


    【解决方案1】:
    #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);
    
    }
    

    【讨论】:

      【解决方案2】:
      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);
      }
      

      【讨论】:

        【解决方案3】:

        first 应该是一个指针。将其更改为 struct node *first;

        在主初始化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);
        }
        

        【讨论】:

          【解决方案4】:

          如果你想用链表做一个堆栈,把first变量作为一个指针。然后,当您将一个新节点压入堆栈时,通过 malloc() 在堆内存上分配来创建一个新节点。我知道你打算用它来指向栈顶。对吧?

          在您的代码中,first 变量被新节点覆盖,因为它不是指针变量而是值变量。这导致丢失堆栈的顶部节点。

          【讨论】:

            【解决方案5】:

            当您必须自己管理内存时,如 C 语言要求的那样,您需要知道称为堆栈和堆的内存区域之间的区别。 (这个“堆栈”与您在程序中创建的数据结构略有不同。)

            您的push() 函数正在堆栈上创建一个新节点;当函数退出时,堆栈被弹出并且新节点占用的内存可供抢夺。您看到输入的值是因为您的程序非常简单。如果它正在调用执行其他操作的其他函数,它们几乎肯定会覆盖堆栈的那一部分,当您调用 pop() 时,您会看到垃圾。

            正如其他人所指出的,您需要使用函数malloc()free(),它们为您提供来自堆而不是堆栈的内存。

            【讨论】:

              【解决方案6】:

              问题在于first 是一个单一的全局node,它是您唯一拥有的node(除了在您对push 的调用中的临时本地node)。

              这一行:

                  first = newNode;
              

              只需将newNode 的内容复制到first;由于newNode.next 指向first,这意味着现在first.next 指向first,所以你有一个单元素循环链表。

              同样,这一行:

                  first = *(first.next);
              

              只需将*(first.next)的内容复制到first;这是一个空操作,因为(由于上述原因),*(first.next) first

              要解决这个问题,你实际上需要动态创建节点,使用malloc(和free)。你的全局first 变量应该是一个指针——一个node *——它总是指向堆栈的顶部元素。 (更好的是,您的 pushpop 函数应该将 first 作为参数,而不是将其作为全局变量。这些函数不需要只允许存在单个堆栈。)

              【讨论】:

                【解决方案7】:

                &amp;first 的值是多少?提示,它总是一样的,因为first 是静态分配的。即使你改变结构的内容,地址也不会改变。这可能会告诉您为什么push 中存在错误。如果您要拥有不同大小的结构,则需要使用 mallocfree

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-04-08
                  • 2013-09-27
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-07-08
                  • 1970-01-01
                  • 2010-10-08
                  相关资源
                  最近更新 更多