【问题标题】:implementing a dynamically sized stack using an array,elements printing error使用数组实现动态大小的堆栈,元素打印错误
【发布时间】:2015-06-05 00:24:38
【问题描述】:

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

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

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

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

在 pop 函数中打印“堆栈为空”消息,并在尝试从空堆栈中弹出数据时返回值 -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;
        }
    

【问题讨论】:

  • 请将代码删除为 MCVE 并正确格式化(每个缩进级别 4 个空格)。
  • “它没有获取所需数量的值”。那就是它没有做的事情,那么它在做什么呢(例如,在 X 值之后崩溃?获取所有值但忽略它们?...?)。 “我无法打印元素”..再一次,这就是它没有做的事情,那么它在做什么呢?
  • 1)p-&gt;a=(int *)malloc(p-&gt;maxSize * sizeof(stack)); 应该是p-&gt;a=(int *)malloc(maxSize * sizeof(int));
  • @Olaf 元素输入和弹出。
  • @Olaf 当我给出 maxSize 3 时,它会正确输入元素,但是如果我在输入 3 个值后给出 4,它开始给我消息堆栈已满。

标签: c pointers dynamic malloc


【解决方案1】:

这段代码有很多地方出错了。

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

其次,这些天没有人会用 -1 初始化顶部。没有任何好处,真的。通常,您将使用 0 进行初始化。然后,如果 p-&gt;top == 0,则堆栈为空。如果p-&gt;maxSize == p-&gt;top,堆栈已满。而栈顶的值(如果不为空)是p-&gt;a[p-&gt;top - 1]

接下来,您的initstack() 函数应该是p-&gt;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];
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    在您的 push() 例程中,您有:

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

    但是您已经在 initstack() 例程中为 p-&gt;a 分配了空间。 此代码正在清除之前存储在堆栈中的所有内容。

    【讨论】:

    • @jimok 现在我应该如何打印。
    【解决方案3】:
    //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;
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-15
      • 2014-12-29
      • 2017-08-15
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-17
      • 2011-11-16
      相关资源
      最近更新 更多