2017-02-12 10 views
1

私はC++の初心者です。コードは割り当ての一部です。プログラムの無限ループに問題があります。私は無限ループがシーケンス(n)で発生することを知っていますが、なぜ無限ループであるのか分かりません。私はプロセスを段階的に評価しましたが、何かが欠けているようです。シンプルなC++関数で無限ループを修正するには?

例:N = 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)と等しくなければなりません。next()は値を返すときにnextNumがどのように変化しないのでしょうか? –

+0

@MTee *それは*ではありません。 'x = next(nextNum)'を宣言に置き、 'x'の* initialization *がどこでも' x'が出現することを意味するわけではないので、これは式next(nextNum)を代入することと等価です。 'x'はプリプロセッサマクロではありません。それは変数です。 – WhozCraig

+0

ああこれは素晴らしい洞察です。 'while ='文のすぐ上にある 'x = next(nextNum);という行は、「xを参照してxをnext(nextNum)にしたいとき」を意味するかもしれないと思うかもしれませんが、そうではありません!単に 'next(nextNum)'の値で 'x'を初期化すると言うだけです。その時点から、 'x'はあなたが何か他のものに変更しない限り、あなたが最初に初期化した値になります。重要なのは、 '='は**平等の意味ではなく**、**の割り当てを意味します。 – rwols

-1

実際にこのコードを使用して、雹のシーケンスを生成することができます。 @NPEは、whileループでnextNumの変化しない値について示唆まずとして

#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

私はそれに従わないために従うべき具体的なガイドラインがあります。ありがとうtho。 –

+0

さて、このコードで理解しなければならないことは、nからnが1になるまでループを実行します.nの値はループ内で変更されます.nの新しい値が生成された後、コンソールに出力されます。 –

0

。変数xを使わずにnextNumの値を直接割り当てることができます。

第2のことは、なぜ使用しているのですかはループ内の文を中断します。 次のように書くことができます: -

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

は今 nextNumループの反復ごとに新たな価値を持つことになります。 これがあなたを助けてくれることを願っています。 :-)

+0

申し訳ありませんが、** break **文がそこにありましたので、私は実際に端末の出力を見ることができました。また、私の教授はループ内のコールバックを駄目にしています。なぜなら私は最初に変数** x **で** nextNum **を持っていたからです。 –

+0

コールバックをループ外に保つことは良い方法です。しかし、ここでループ状態はそのコールバックに依存しているため、ループに入れなければなりません。 – Ashu

+0

@M Tee break文は、端末上の出力を見るためのものではありません。そのためにprintコマンドを使います。 ** break **文はループを終了するために使用されるため、このループに** break **を置くと、1回の反復しか機能しません。 – Ashu