0

嗨,我的堆栈数据结构程序有问题。似乎当我定义我的数组的大小/数组的想象大小只是为了通过循环调用它时,当我输入数据或推送时,我定义或指定的大小正在耗尽或被编辑。

例如。我输入 5 作为尺寸并选择推送,然后添加 2。它工作正常。但是如果我选择再次推送数据,它现在将传递给 size 变量。我不知道发生了什么...

#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define p printf
#define s scanf

int top;
int ar[1];
int size;

main()
{
    void push();
    int opt, num;
    char cont[] = { 'y' };
    clrscr();

    p("Stacking Program");
    p("\n\nData Size: ");
    s("%d", &size);
    p("\n");

    while((cont[0] == 'y') || (cont[0] == 'Y'))
    {
        clrscr();
        p("Stacking Program");
        p("\n\nData Size: %d\n\n", size);
        p("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
        s("%d", &opt);
        p("\n");

        switch(opt) {
            case 1:
                pop();
                break;
            case 2:
                if(top > size)
                {
                    p("You can't push more data");
                }
                else
                {
                    p("Enter data for Data[%d]: ", top);
                    s("%d", &num);
                    push(num);
                }
                break;
            case 3:
                pick();
                break;
            case 4:
                view();
                break;
            default:
                p("Your choice is not in the list.");
                break;
        }

        p("\n\nDo you want continue\(Y\/N\)?");
        s("%s", &cont[0]);
    }
}

pop()
{
    int a;
    if(top < 0)
    {
        p("Stack empty.");
        return 0;
    }
    else
    {
        a = ar[top];
        p("\(Data[%d] = %d\) removed.", top, a);
        top--;
    }
}
void push(int b)
{
    top++;
    ar[top] = b;
}
pick()
{
    if(top < 0)
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        p("\(Data[%d] = %d\) is the last data.", top, ar[top]);
    }
}
view()
{
    int i;
    if(top < 0)
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        for(i = 1; i < (top + 1); i++)
        {
            p("Data[%d] = %d\n", i, ar[i]);
        }
    }
}
4

2 回答 2

0

如果您不想动态调整数组大小,另一种方法是分配一个包含 MAXSIZE 元素的数组,其中 MAXSIZE “足够大”。此外,还有一些其他评论:

您在程序的顶部声明了一个大小为 1 的字符数组:

char cont[] = { 'y' };

但是稍后在您的 scanf 行中,您尝试使用它:

s("%s", &cont[0]);

即使用户只键入一个字符,这也会溢出缓冲区,因为 %s 假定缓冲区至少有两个可用字节,一个用于字符,一个用于 '\0'。可能的修复:

char cont[] = { 'y', '\0' };
// ...
s("%1s", cont);

请注意,cont 与 &cont[0] 的表达方式相同且更常见。

另一个问题是,如果打开警告,编译器可能会捕获到一些问题:所有函数都应该在被提及之前进行原型化,没有显式返回类型的函数应该使用 int 类型声明,并且你不应该让函数在没有即使您显式或隐式声明它,也会返回一个值。此外,'(' 和 ')' 不需要在字符串文字中转义。

这是一个修改后的版本,其中注明了更改。我重新定义了 clrscr() 因为我在这个系统上没有 conio.h:

#include <stdio.h>
#include <ctype.h>
// #include <conio.h>
#define clrscr() printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#define p printf
#define s scanf

#define MAXSIZE 500


// prototypes [Changed]
int pop();
void push(int b);
int pick();
int view();

int top;
int ar[MAXSIZE];
int size;

int main()
{
    int opt, num;
    char cont[] = { 'y', '\0' }; // [Changed]
    clrscr();
    p("Stacking Program\n\n");

    // keep asking until we get a valid size [Changed]
    for (;;)
    {
        p("Data Size: ");
        s("%d", &size);
        if (size > 0 && size < MAXSIZE)
            break;
        printf("Not a valid size!\n");
    }
    p("\n");

    while((cont[0] == 'y') || (cont[0] == 'Y'))
    {
        clrscr();
        p("Stacking Program");
        p("\n\nData Size: %d\n\n", size);
        p("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
        s("%d", &opt);
        p("\n");

        switch(opt) {
            case 1:
                pop();
                break;
            case 2:
                if(top > size)
                {
                    p("You can't push more data");
                }
                else
                {
                    p("Enter data for Data[%d]: ", top);
                    s("%d", &num);
                    push(num);
                }
                break;
            case 3:
                pick();
                break;
            case 4:
                view();
                break;
            default:
                p("Your choice is not in the list.");
                break;
        }

        p("\n\nDo you want continue(Y/N)?");
        s("%1s", cont); // [Changed]
    }
    return 0;
}

int pop()
{
    int a;
    if(top == 0) // [Changed]
    {
        p("Stack empty.");
        return 0;
    }
    else
    {
        top--; // [Changed]
        a = ar[top];
        p("(Data[%d] = %d) removed.", top, a);
        return a; // [Changed]
    }
}

void push(int b)
{
    ar[top] = b;
    top++; // [Changed]
}

int pick()
{
    if(top == 0) // [Changed]
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        p("(Data[%d] = %d) is the last data.", top, ar[top-1]); // [Changed]
        return -1; // [Changed]
    }
}

int view()
{
    int i;
    if(top < 0)
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        for(i = 0; i < top; i++)  // [Changed]
        {
            p("Data[%d] = %d\n", i, ar[i]);
        }
        return -1;  // [Changed]
    }
}
于 2012-09-28T10:27:59.177 回答
0

您需要在运行时使用用户输入的大小定义数组的大小。代替:

int top;
int ar[1];
int size;

...

int top = -1;
int *ar = NULL;
int size = 0;

然后从用户那里获得大小后:

   if ( size > 0 )
   {
      ar = malloc(size * sizeof(int));
      if ( ar == NULL )
      {
         printf("ERROR: malloc() failed\n");
         exit(2);
      }
   }
   else
   {
      printf("ERROR: size should be positive integer\n");
      exit(1);
   }


   ....
      p("\n\nDo you want continue(Y/N)?");
      s("%s", &cont[0]);
   }
   free(ar);


} // end of main

我认为 view() 中的 for 循环应该是:

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

case 2:
    if ( top == ( size - 1 ))
于 2012-09-27T23:14:13.327 回答