2017-02-12 2 views
1

Я новичок в C++, и код является частью задания. У меня проблема с бесконечным циклом программы. Я знаю, что бесконечный цикл встречается в последовательности (n), но я не понимаю, почему это бесконечный цикл. Я оценил процесс шаг за шагом, но, похоже, что-то не хватает.Как исправить бесконечный цикл в простой функции C++?

Ex: проблемы я столкнулся: п = 7, последовательность напечатает: 7 22 22 22 22 22

#include <cstdio> 
using namespace std; 

// next(n) returns the value that follows n in the hailstone sequence. 
// Example: next(7) = 22, next(22) = 11, etc. 
// Since the hailstone sequence ends at 1, n is required to be > 1. 

int next (int n) 
{ 
    while (n > 1) 
    { 
    if (n%2 == 0) 
    { 
     return n/2; 
    } 
    else 
    { 
     return 3*n+1; 
    } 
    } 
    return 1; 
} 

// sequence(n) executes next(n) in a loop to print the next integer(s) 
// in the hailstorm sequence, starting from n until ending with 1. 

void sequence(int n) 
{ 
    int nextNum = n, x = next(nextNum); 
    while (nextNum > 1) 
    { 
    printf("%i", nextNum); 
    nextNum = x; 
    break; 
    } 
    if (nextNum == 1) 
    { 
    printf("%i", 1); 
    } 
} 

int main() 
{ 
    int n; 
    printf("Enter n: "); 
    scanf("%i", &n); 

    sequence(n); 

    return 0; 
} 

ответ

2

Рассмотрим следующее:

while (nextNum > 1) 
{ 
    printf("%i", nextNum); 
    nextNum = x; 
    break; 
} 

Здесь x никогда не меняется. Следовательно, nextNum также никогда не меняется. Это заставляет цикл выполняться бесконечно или вообще не выполняться.

вы имели в виду, чтобы позвонить next()внутри тело цикла, не вне?

Также обратите внимание, что while (n > 1) в next() является не-оператором, учитывая, что тело цикла всегда returns.

+0

Эта строка должна быть эквивалентна nextNum = next (nextNum), как это, что nextNum не изменяется, когда next() возвращает значение? –

+0

@MTee * но не *. Просто потому, что вы положили 'x = next (nextNum)' на объявление и * инициализацию * 'x', не означает, что везде' x' появляется в дальнейшем, эквивалентно замене выражения 'next (nextNum)'. 'x' не является макросом препроцессора. Это переменная. – WhozCraig

+0

А это отличное понимание. Вы можете подумать, что строка 'x = next (nextNum);' чуть выше оператора 'while' может означать« каждый раз, когда я ссылаюсь на x, я хочу, чтобы он был следующим (nextNum) », но это не тот случай! Вы просто говорите, что вы * инициализируете * 'x' со значением' next (nextNum) '. С этого момента 'x' будет * всегда * быть тем значением, с которым вы его сначала инициализировали, если вы не измените его на что-то еще. Важно то, что '=' does ** not ** означает равенство, это означает ** присвоение **. – rwols

-1

Вместо этого вы можете использовать этот код, который генерирует последовательность градиента.

#include <cstdio> 
using namespace std; 
int main() 
{ 
    int n; 
    printf("Enter n: "); 
    scanf("%i", &n); 

    printf("%i\t",n); 
    while(n>1) 
    { 
    if(n%2==0) 
    { 

     n=n/2; 
    } 
    else 
    { 

     n=(3*n)+1; 
    } 

    printf("%i\t",n); 

} 

    return 0; 
} 
+0

Плохой ответ. Другие улучшают свои навыки вырезания и вставки, что OP учится на этом? По крайней мере, объясните, что вы сделали и почему. – user4581301

+0

У меня есть конкретные рекомендации, чтобы следовать, поэтому я не буду использовать это. Спасибо, тo. –

+0

Ну вот что нужно понимать в этом коде. Он запускает цикл из n, пока n не станет равным 1. Значение n изменяется внутри цикла. После создания нового значения n оно выводится на консоль. –

0

Во-первых, как @NPE предполагает о не изменяя значения nextNum в то время как петли. Вы можете просто присвоить значение nextNum напрямую, не используя переменную x.

Во-вторых, почему вы используете break инструкция в цикле. Вы можете написать следующим образом: -

while (nextNum > 1) 
{ 
    printf("%i", nextNum); 
    nextNum = next(nextNum); 
} 

Теперь nextNum будет иметь новое значение в каждой итерации цикла. Надеюсь, это вам поможет. :-)

+0

Извините, инструкция ** break ** была там, чтобы я мог видеть выходы в терминале.Кроме того, мой профессор отказывается от обратных вызовов в циклах, поэтому у меня было ** nextNum ** в переменной ** x ** изначально. –

+0

Это хорошая практика для поддержания обратных вызовов вне цикла. Но здесь ваше условие цикла зависит от этого обратного вызова, поэтому вам нужно поместить его в цикл. – Ashu

+0

@M Оператор отключения Tee не предназначен для просмотра выходов на терминалах, для этого используйте команды печати. ** break ** statement используется для завершения цикла, поэтому, если вы положите ** break ** в этом цикле, будет работать только одна итерация. – Ashu

Смежные вопросы