Почему эта программа зацикливается иногда и не всегда - PullRequest
0 голосов
/ 22 мая 2018

Я успешно решил проект по программированию из книги К. Н. Кинга "Программирование на C: современный подход".

Программа отлично работает, но иногда заходит в бесконечный цикл.Я не понимаю причину этого.

Я использовал случайную функцию, которая будет давать случайные значения в диапазоне от 0 до 3, и я использовал достаточные условия для обработки всех четырех случайных значений.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
    char walk[10][10];
    int direction,currenti=5,currentj=5;

    int i,j;
    for(i=0; i<10; i++)
    {
        for(j=0; j<10; j++)
        {
            walk[i][j]='.';
        }
    }
    srand((unsigned) time(NULL));
    for(i=0; i<26;)
    {
        direction=rand()%4;
        printf("%d ",direction);
        if(direction==0&&walk[currenti][currentj-1]=='.'&&(currentj-1)>0&&(currentj-1)<10)
        {
            currentj=currentj-1;
            walk[currenti][currentj]='A'+i;
            i++;
        }
        else if(direction==1&&walk[currenti][currentj+1]=='.'&&(currentj+1)>0&&(currentj+1)<10)
        {
            currentj=currentj+1;
            walk[currenti][currentj]='A'+i;
            i++;
        }
        else if(direction==2&&walk[currenti-1][currentj]=='.'&&(currenti-1)>0&&(currenti-1)<10)
        {
            currenti=currenti-1;
            walk[currenti][currentj]='A'+i;
            i++;
        }
        else if(direction==3&&walk[currenti+1][currentj]=='.'&&(currenti+1)>0&&(currenti+1)<10)
        {
            currenti=currenti+1;
            walk[currenti][currentj-1]='A'+i;
            i++;
        }
    }
    for(i=0; i<10; i++)
    {
        for(j=0; j<10; j++)
        {
            printf("%c ",walk[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Когда вы вводите угол и массив вокруг него содержит только точки, у вас будет бесконечный цикл.Это происходит только иногда из-за случайного поведения, конечно

0 голосов
/ 22 мая 2018

Поскольку ваша прогулка является случайной, вы можете войти в условие, когда невозможно двигаться дальше, независимо от того, какое число и i не будет увеличено

Пример бесконечного цикла (ваша программа переходит от 1 до 9)

1 2 3 . . . . . . .
8 9 4 . . . . . . .
7 6 5 . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .

На шаге 9 ваша программа будет заблокирована независимо от того, что будет следующим direction, поскольку она заблокировала все возможные последующие шаги.

Конечно, существует множество вариантовТакая ситуация, но это также означает, что есть ситуация, когда ваша программа заблокировала себя перед выполнением своих 26 шагов.

Вы должны обнаружить такое условие, чтобы прервать цикл раньше.

0 голосов
/ 22 мая 2018

Я думаю, что только при быстром взгляде, потому что в вашем основном цикле for вы увеличиваете i только при определенных условиях, и вполне вероятно, что ни один из них или не выполняется, что означает, что i++ будетне вызывать.

Лучший способ убедиться в этом - поместить предложение else, где вы правильно обрабатываете дело, распечатав сообщение или вставив утверждение, если вы никогда не достигнете этого случая.

В качестве меры предосторожности, когда у вас есть предложения if / else if, у вас всегда должно быть предложение else, в котором вы обрабатываете значение «если все остальное терпит неудачу», где вы либо правильно обрабатываете ошибку, или утверждайте, если код никогда не достигнет предложения else.

Также, в качестве примечания, вы должны рассмотреть возможность использования пробелов, чтобы сделать ваш код немного легче для чтения, например:

if (direction == 3 && walk[currenti + 1][currentj] == '.' && (currenti + 1) > 0 && (currenti + 1) < 10)
...