while循环为什么不终止?

问题描述 投票:0回答:1

编写代码是为了使用堆栈操作解决汉诺塔问题,但输出会无限期地打印出来。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 100

struct stack{
int a[MAX_SIZE];
int top;
}x, y, z;

typedef struct stack stk;

void push(stk *s, char n)
{
  if(s->top == MAX_SIZE-1)
    printf("Stack Overflow\n");
  else
    s->a[++s->top] = n;
}

int pop(stk *s)
{
  if(s->top < 0)
  {
    printf("Stack Underflow\n");
    return -1;
  }
  else
  {
    return s->a[s->top--];
  }
}

int top(stk *s)
{
  if(s->top < 0)
  {
    return -1;
  }
  else
  {
    return s->a[s->top];
  }
}

int isEmptyStack(stk *s)
{
  if(s->top < 0)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

int isFullStack(stk *s)
{
  if(s->top == MAX_SIZE - 1)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

int size(stk *s)
{
  return s->top;
}

int main()
{
    x.top = -1;
    y.top = -1;
    z.top = -1;

    int n;
    printf("Enter number of disks: ");
    scanf("%d", &n);

    for(int i=0;i<n;i++)
    {
        push(&x, i+1);
    }

    if(n > 0)
    {
        while(size(&z) < n-1)
        {
            if(n % 2 != 0)
            {
                if(top(&x) > top(&z))
                {
                    push(&z, pop(&x));
                    printf("X to Z\n");
                }
                if(top(&z) > top(&x))
                {
                    push(&x, pop(&z));
                    printf("Z to X\n");
                }

                if(top(&x) > top(&y))
                {
                    push(&y, pop(&x));
                    printf("X to Y\n");
                }
                if(top(&y) > top(&x))
                {
                    push(&x, pop(&y));
                    printf("Z to X\n");
                }

                if(top(&y) > top(&z))
                {
                    push(&z, pop(&y));
                    printf("Y to Z\n");
                }
                if(top(&z) > top(&y))
                {
                    push(&y, pop(&z));
                    printf("Z to Y\n");
                }
            }

            else
            {
                if(top(&x) > top(&y))
                {
                    push(&y, pop(&x));
                    printf("X to Y\n");
                }
                if(top(&y) > top(&x))
                {
                    push(&x, pop(&y));
                    printf("Y to X\n");
                }

                if(top(&x) > top(&z))
                {
                    push(&z, pop(&x));
                    printf("X to Z\n");
                }
                if(top(&z) > top(&x))
                {
                    push(&x, pop(&z));
                    printf("Z to X\n");
                }

                if(top(&y) > top(&z))
                {
                    push(&z, pop(&y));
                    printf("Y to Z\n");
                }
                if(top(&z) > top(&y))
                {
                    push(&y, pop(&z));
                    printf("Z to Y\n");
                }   
            }
        }
    }

    return 0;
}

我期待条件

size(&z) < n-1
变成
0
这将终止循环,但循环没有终止。

航站楼:

Enter number of disks: 3
*Out of control output*

有人建议我使用调试器,但我不知道如何使用它,因为我只是在学习使用它。

c
1个回答
0
投票

无限循环意味着循环条件(在本例中为

size(&z) < n-1
)永远保持为真。由于右侧 (rhs)
n-1
固定为
n = 3
这意味着您期望
size(&z)
至少增加到 2 但它永远不会增加。从输出中我们看到一个重复的循环:

Z to X
X to Y
Z to X
X to Z
Z to X
...

这告诉我们,我们将一个值推到

z
并立即将其弹出,因此我们永远不会取得进展。

我建议你修改你的界面,这样你的错误域(-1)和值域就不会重叠。如果你

push(..., -1)
现在你不知道什么时候
top(...)
返回 -1 如果它是一个错误或者它恰好是你推送的最后一个值。
pop()
有同样的问题,而且,来电者也不知道,但至少有一条错误消息。

在您的情况下,要么禁止推送 -1,要么让函数返回操作状态并通过您传入的指针返回值(此处使用常量 OK 以提高可读性):

#define OK 0

int push(stk *s, char n) {
    if(s->top == MAX_SIZE-1) {
        printf("Stack Overflow\n");
        return !OK;
    }
    s->a[++s->top] = n;
    return OK;
}

int pop(stk *s, int *v) {
    if(s->top < 0) {
        printf("Stack Underflow\n");
        return !OK;
    }
    *v = s->a[s->top--];
    return OK;
}
© www.soinside.com 2019 - 2024. All rights reserved.