使用数组实现动态大小的堆栈,元素打印错误

时间:2015-06-05 00:24:38

标签: c pointers dynamic malloc

结构堆栈有一个指向动态分配数组的指针'a'(用于保存堆栈的内容),一个整数'maxSize',它保存了这个数组的大小(即可以存储的最大数据量)保存在这个数组中)和一个整数'top',它存储堆栈中顶部元素的数组索引。

在initstack函数中,将top的值初始化为-1并初始化maxSize的值。 当尝试将数据推入完整堆栈时,在推送功能中打印消息“堆栈已满”。 在pop函数中打印消息“Stack is empty”,并在尝试从空堆栈中弹出数据时返回值-1000。

在initstack函数中,将top的值初始化为-1并初始化maxSize的值。

当尝试将数据推入完整堆栈时,在推送功能中打印消息“堆栈已满”。

在pop函数中打印消息“Stack is empty”,并在尝试从空堆栈中弹出数据时返回值-1000。

请注意,“堆栈内容为”的语句位于main函数中。在显示功能中,如果堆栈为空,则打印“{}”。

我的代码出现问题:

  • 没有采取所需的数值。
  • 其次,我无法打印元素。

     #include<stdio.h>
     #include<stdlib.h>
     struct stack
       {
         int * a;
         int top;
         int maxSize;
       };
    void initstack(struct stack * p, int maxSize);
    void push(struct stack * p, int item);
    void display(struct stack p);
    int pop(struct stack * p);
    void printMenu();
    
      int main()  
       {
         struct stack p;
         int data,ch, data1, m;
         printf("Enter the maximum size of the stack\n");
         scanf("%d",&m);
         initstack(&p,m);
         do
           {
             printMenu();
             printf("Enter your choice\n");
             scanf("%d",&ch);
             switch(ch)
               {
                  case 1:
                  printf("Enter the element to be pushed\n");
                  scanf("%d",&data);
                  push(&p, data);
                  break;
    
                  case 2:
                  data1 = pop(&p);
                  if(data1 != -1000)
                  printf("The popped element is %d\n",data1);
                  break;
    
                  case 3:
                  printf("The contents of the stack are");
                  display(p);
                  printf("\n");
                  break;
    
                  default:
                  return 0;
               }
           }
        while(1);
        return 0;
      }
    
       void printMenu()
         {
          printf("Choice 1 : Push\n");
          printf("Choice 2 : Pop\n");
          printf("Choice 3 : Display\n");
          printf("Any other choice : Exit\n");
         }
    
        void initstack(struct stack * p, int maxSize) 
         {
           p->top=-1;
           p->maxSize=maxSize;
         }
    
       void push(struct stack * p, int item) 
         {
           if (p->top == p->maxSize-1) 
             {
              printf("Stack is full\n");
              return;
             }
        p->a = (int *)malloc(sizeof(int));
        p->top++;
        p->a[p->top] =item;
        p->maxSize--;
    
       }
    
        void display(struct stack p) 
         {
           struct stack *p1;
           p1=&p;
           int a[30],n=0,i;
           for (i = p1->top ; i >= 0; i--)
            {
              printf("\n%d", p1->a[i]);
    
            }
    
          }
    
         int pop(struct stack * p) 
          {
            int num;
            if(p->top == -1)
             {
               printf("Stack is empty\n");
               return -1000;
             }
          num = p->a[p->top];
          p->top--;
          return num;
        }
    

3 个答案:

答案 0 :(得分:3)

此代码中出现了一些问题。

首先,Olafs评论正确格式化代码可能会显得苛刻,但这是合理的。根据您使用的编辑器,只需2次击键即可。 (例如Visual Studio中的CTRL-k-f)。为了将代码放到SO上的问题,秘密是(再次在VS中):CTRL-a(全部标记)TAB CTRL-C并且您需要源代码在此站点上显示为源代码所需的初始4个缩进。

其次,这些天没人会用-1初始化top。真的,没有任何好处。通常,您将初始化为0.然后,如果p->top == 0,则堆栈为空。如果p->maxSize == p->top,堆栈已满。堆栈上的最高值(如果不是空的)是p->a[p->top - 1]

接下来,您的initstack()函数应该是p->a = malloc(maxSize * sizeof(int));。除非有特殊要求创建一个懒堆栈或诸如此类的东西。

您的显示功能堆栈参数按值传递(忘记'*')。

void display(struct stack *p) {
    if (NULL != p)
    {
        if (NULL != p->a)
        {
            for (int i = 0; i < p->top; i++)
            {
                printf("%d\n", p->a[i]);
            }
        }
    }
}

此外,通常没有足够的参数检查。如果有人传递指向函数的指针,则该函数负责在它为NULL时不访问它。 (防御性编程)。通常,函数不负责破坏内存或执行非法访问。

接下来,只要你有一个init函数,你也应该创建一个清理函数。这两者兼而有之。 initstack()的签名有点缺乏,顺便说一下。只要存在可能失败的事情(这里:malloc()),该函数就会失败,因此它应该具有状态返回值,因此调用者可以对堆栈未按照实际需要进行实际初始化的事实作出反应。内存不足(或堆碎片或其他任何可能导致malloc失败的原因)。

void initstack(struct stack * p, int maxSize) {
    p->top = 0;
    p->maxSize = maxSize;
    p->a = malloc(maxSize * sizeof(int));
}

void uninitstack(struct stack* p) {
    free(p->a);
    p->a = NULL;
    p->maxSize = 0;
    p->top = 0;
}

这里有一些固定的推送功能,带有基本的错误检查代码:

void push(struct stack * p, int item) {
    if (p == NULL){
        printf("Invalid argument. p == NULL.\n");
    }
    if (p->a == NULL) {
        printf("Stack not initialized.\n");
            return;
    }
    if (p->top == p->maxSize) {
        printf("Stack is full\n");
        return;
    }
    if (p->top < p->maxSize) {
        p->a[p->top] = item;
        p->top++;
    }
}

最后,至少相应的pop功能:

int pop(struct stack * p) {
    if (NULL != p)
    {
        if (NULL != p->a) {
            if (p->top == 0) {
                printf("{}\n");
                return -1000;
            }
            else {
                p->top--;
                return p->a[p->top];
            }
        }
    }
}

答案 1 :(得分:1)

push()例程中,您有:

 p->a = (int *)malloc(sizeof(int));

但您已经在p->a例程中为initstack()分配了空间。 这段代码消除了以前存储在堆栈中的任何内容。

答案 2 :(得分:0)

//This program works perfectly

   #include<stdio.h>
     #include<stdlib.h>
     struct stack
       {
         int * a;
         int top;
         int maxSize;
       };
    void initstack(struct stack * p, int maxSize);
    void push(struct stack * p, int item);
    void display(struct stack p);
    int pop(struct stack * p);
    void printMenu();

      int main()  
       {
         struct stack p;
         int data,ch, data1, m;
         printf("Enter the maximum size of the stack\n");
         scanf("%d",&m);
         initstack(&p,m);
         do
           {
             printMenu();
             printf("Enter your choice\n");
             scanf("%d",&ch);
             switch(ch)
               {
                  case 1:
                  printf("Enter the element to be pushed\n");
                  scanf("%d",&data);
                  push(&p, data);
                  break;

                  case 2:
                  data1 = pop(&p);
                  if(data1 != -1000)
                  printf("The popped element is %d\n",data1);
                  break;

                  case 3:
                  printf("The contents of the stack are");
                  display(p);
                  printf("\n");
                  break;

                  default:
                  return 0;
               }
           }
        while(1);
        return 0;
      }

       void printMenu()
         {
          printf("Choice 1 : Push\n");
          printf("Choice 2 : Pop\n");
          printf("Choice 3 : Display\n");
          printf("Any other choice : Exit\n");
         }

        void initstack(struct stack * p, int maxSize) 
         {
      p->maxSize=maxSize;
      p->a=(int*)malloc(maxSize*sizeof(int));
      p->top=-1;
         }

       void push(struct stack * p, int item) 
         {
      if (p->top == p->maxSize - 1) {
          printf("Stack is full\n");
          return ;
       }
       p->top++;
       p->a[p->top] = item;
         }

        void display(struct stack p) 
         {
      int i,jp=0;
       for (i =0; i<=p.top; i++)
       {
          // if(p.top!=0)
           jp++;
          printf(" %d", p.a[i]);
       }
       if(jp==0)
       printf(" {}");
          }

    int pop(struct stack * p) 
    {
       int num;
       if (p->top == -1) {
          printf("Stack is empty\n");
          return -1000;
       }
       num = p->a[p->top];
       p->top--;
       return num;
        }