Заменить разрыв в C

#c #do-while #break

#c #do-while #перерыв

Вопрос:

Я пишу программу, предназначенную для компьютерной игры mastermind. Когда я впервые написал это, учитель не сказал нам, что мы не можем использовать break, поэтому я это сделал. Но не разрешается использовать break. Я пытаюсь найти способ заменить разрыв, но мне трудно понять изменение логики. Вот мой рабочий исходный код:

     //If number of matches is not equal to length, print the hints and check for pica's
    if(matches != LENGTH) {
        //First, print as many fermi hints as matches
        for(int i = 0; i < matches; i  ) {
            printf("fermi ");
        }
        //Then, second loop to check for pica hints
        for(int i = 0; i < LENGTH; i  ) {
            //We use the i index if not used before
            if(!usedNum[i]) {
                for(int j = 0; j < LENGTH; j  ) {
                    //Check if the digit is the same for given indices if not used already on guess
                    if(!usedGuess[j] amp;amp; num[i] == guess[j]) {
                        //If so, we have a match but on incorrect position
                        usedNum[i] = true;
                        usedGuess[j] = true;
                        used  ;
                        printf("pica ");
                        break;
                    }
                }
            }
        }
        //If no used numbers, we print "bagels"
        if(used == 0) {
            printf("bagels");
        }
        printf("n"); //line break after hints
    }
    //Finally, we return the num of matches
    return matches;
}
 

И моя попытка превратить его в цикл do while.

  if(matches != LENGTH) {
        //First, print as many fermi hints as matches
        for(int i = 0; i < matches; i  ) {
            printf("fermi ");
        }
        //Then, second loop to check for pica hints
        for(int i = 0; i < LENGTH; i  ) {
            //We use the i index if not used before
            if(!usedNum[i]) {
                do {
                    //Check if the digit is the same for given indices if not used already on guess
                        int j = 0;
                        //If so, we have a match but on incorrect position
                        usedNum[i] = true;
                        usedGuess[j] = true;
                        used  ;
                        printf("pica ");                        
                    } while (usedGuess[j] || num[i] == guess[j]);
            } 
            }
        }
        //If no used numbers, we print "bagels"
        if(used == 0) {
            printf("bagels");
        }
        printf("n"); //line break after hints
    }
    //Finally, we return the num of matches
    return matches;
}
 

Читаю об имплантациях. Мой исходный код может быть указан как do this until. Однако новый код, использующий цикл while, делает это, пока это утверждение верно. Итак, для исходного кода у меня были условия остановки для моего нового кода, я должен придумать условия продолжения, верно? Будет ли лучший логический цикл для использования?

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

Комментарии:

1. Кажется, ваш break; можно заменить j = LENGTH; . Каковы точные ограничения?

2. Большинство требований к этому не имеют отношения. как будто нет глобальной переменной и только материал для этой последней лекции, так что основные вещи. но ваше предложение сработало, не знаю, почему я об этом не подумал. Большое спасибо, что вы работали над этим весь день, лол

Ответ №1:

Есть несколько способов, которые вы можете использовать вместо break; . Поскольку ограничение использования break; не кажется разумным, и могут быть некоторые другие ограничения, я не могу сказать, будут ли приняты все способы.

Изменение значения j для выхода из цикла:

 for(int j = 0; j < LENGTH; j  ) {
    if(!usedGuess[j] amp;amp; num[i] == guess[j]) {
        /* snipped */
        j  = LENGTH;
    }
}
 

Использование другого флага для выхода из цикла:

 bool found = false;
for(int j = 0; !found amp;amp; j < LENGTH; j  ) {
    if(!usedGuess[j] amp;amp; num[i] == guess[j]) {
        /* snipped */
        found = true;
    }
}
 

Использование goto (возможно, некоторые люди не одобряют, но это допустимый синтаксис):

 for(int j = 0; j < LENGTH; j  ) {
    if(!usedGuess[j] amp;amp; num[i] == guess[j]) {
        /* snipped */
        goto after_the_loop;
    }
}
after_the_loop:;
 

Комментарии:

1. Спасибо, следите за тем, в чем преимущество break, если это можно сделать с помощью других методов? Или это единственный вариант из-за этой уникальной ситуации.

2. break; может немедленно выскочить из цикла. Первый и второй варианты здесь доступны, потому что после этого нет кода для выполнения, чтобы вызвать видимый эффект. goto также можно немедленно выйти из цикла, но может быть сложнее понять намерение.

3. break выражает намерение четко и лаконично. Часто это намного проще в использовании, чем опции, которые полагаются на выполнение условия завершения цикла, и оно более устойчиво к изменениям кода, чем такие методы. goto Подход также обладает этими свойствами, хотя он может быть не таким понятным, как break , и goto имеет незаслуженно плохую репутацию. break здесь лучше, но иногда бывают случаи, когда goto это правильный инструмент для работы.

Ответ №2:

Что-то не так с вашим циклом while, вы инициализируете j равным 0 внутри цикла.

 for(int i = 0; i < LENGTH; i  ) {
    if (!usedNum[i]) {
        int j=0, k=0;
        while (j < LENGTH amp;amp; !k) {
           if(!usedGuess[j] amp;amp; num[i] == guess[j]) {
                usedNum[i] = true;
                usedGuess[j] = true;
                used  ;
                k  ;
                printf("pica ");
            }
            j  ;
        }
    }
}
 

Я думаю, это должно сработать.

Ответ №3:

Для случая, подобного вашему, я бы уделил особое внимание объединению внутреннего условия с условием цикла:

                 int j;
                for (j = 0; j < LENGTH amp;amp; (usedGuess[j] || num[i] != guess[j]); j  ) /* empty */ ;
                if (j < LENGTH) {
                    // we have a match, but on an incorrect position
                    usedNum[i] = true;
                    usedGuess[j] = true;
                    used  ;
                    printf("pica ");
                }
 

Цикл просто ищет индекс j , который удовлетворяет всем требуемым условиям. Если он оставляет j меньше, чем LENGTH при его завершении, тогда вы знаете, что это конечное значение j является тем, которое удовлетворяет и всем другим условиям.