代码完成,但会产生无限循环?

时间:2016-10-13 05:04:30

标签: c++ loops infinite

我正在尝试打印下面这样的模式,我运行的代码没有错误,但它产生了一个无限循环,我不确定为什么;

*
**
***
****
****
***
**
*

任何指导或帮助都会很棒!感谢

#include <iostream>
#include <string>
using namespace std;

// function member
void star(int amountStars, char starShape);

// function
void star(int amountStars, char starShape)
{
    int i;
    string shape = "*"; 
    for (i = 0; i < starShape; i++)
        // loop to increment through 
        cout << shape;

    cout << endl;

    if (starShape == amountStars)
        // if * is equal to the amount of stars (30)
        return; //**************
    star(amountStars, ++starShape); // increase * by one ***********

    for (i = 0; i < starShape; i++)
        cout << shape;
        cout << endl;


}
int main()
{
    int amountStars = 30; // variable to store the amount of stars

    star(amountStars, '*'); // function print for the amount of stars and the shape

    return 0;
}//end main

4 个答案:

答案 0 :(得分:1)

你的star()函数在注释“raise * by one”的行上调用自己,这意味着它是一个递归函数。但终止条件被打破

您使用{* 1}}类型的starShape参数初始化,其字面值为“*”,其ASCII值为42.但您实际上不使用此值作为符号。用于打印的本地字符串变量char。并且您将shape视为计数器,您尝试使用它来结束循环。但它从42开始,只从那里开始,所以它永远不会等于你传入的30的值。

解决此问题的最简单(但不是最佳)方法是将starShape更改为starShape并从int传入0。

main

然后去阅读递归函数和终止条件。 :)

答案 1 :(得分:1)

你将starShape的值设为*,*的ascii值为42,所以你的代码永远不会满足代码:

 if (starShape == amountStars)
        // if * is equal to the amount of stars (30)
        return; //**************

因为42大于30,所以你的循环是无限的。

答案 2 :(得分:1)

您的变量用法不正确。此外,您的递归终止点的位置是有问题的(在这种情况下,由于前者,不正确的变量使用而无效)。最后,您通过使用预增量直接增加本地starShape。没有必要这样做,事实上理由不这样做。

您描述的特定形状是每行字符的递增(上坡)计数,直到达到阈值,然后重复相同的顺序下降(下坡)。这样做的算法是:

void func(const int limit, const int current)
{
    // termination case (note >)
    if (current > limit)
        return;

    // TODO: perform task

    // recurse
    func(limit, current+1);

    // TODO: perform task
}

请注意,根据您给出的示例,如果在递归之前和之后完成相同的任务,则会在图的中心包含重复。在升序,然后是降序线图案的情况下,它看起来像这样:

*
**
***
****
****
***
**
*

如果您不想重复中心线,只需移动递归的位置并将条件更改为匹配而不是超过:

void func(int limit, int current)
{
    // TODO: perform task

    // termination case (note ==)
    if (current == limit)
        return;

    // recurse
    func(limit, current+1);

    // TODO: perform task
}

这将产生如下所示的模式:

*
**
***
****
***
**
*

请注意,中心线重复,因为其他所有都是。

最后,任务本身,可以简单地:

void starline(const int length)
{
    for (int i=0; i<length; ++i)
        std::cout.put('*');
    std::cout.put('\n');
}

您可以使用该实用程序功能并在上面提到的 算法中使用它,它将起作用。

最后,上述所有的参数都是const,因为(a)没有理由为这些算法修改它们,(b)如果你不小心这样做了,你想在编译时捕获它;不是运行时间。

<强>实施例

两种算法都使用前面显示的相同starline()函数。唯一的区别是递归函数和它们发出的结果。

第一个算法及其输出在

之下
#include <iostream>

void starline(const int length)
{
    for (int i=0; i<length; ++i)
        std::cout.put('*');
    std::cout.put('\n');
}

// function
void star(const int amountStars, const int length = 1)
{
    // termination case
    if (length > amountStars)
        return;

    starline(length);
    star(amountStars, length+1);
    starline(length);
}

int main()
{
    star(10);
}

<强>输出

*
**
***
****
*****
******
*******
********
*********
**********
**********
*********
********
*******
******
*****
****
***
**
*

接下来会显示第二个:

#include <iostream>

void starline(const int length)
{
    for (int i=0; i<length; ++i)
        std::cout.put('*');
    std::cout.put('\n');
}

// function
void star(const int amountStars, const int length = 1)
{
    starline(length);

    // termination case
    if (length == amountStars)
        return;

    star(amountStars, length+1);
    starline(length);
}

int main()
{
    star(10);
}

<强>输出

*
**
***
****
*****
******
*******
********
*********
**********
*********
********
*******
******
*****
****
***
**
*

答案 3 :(得分:0)

在你的主体中试试这个

main()
{
    //inside main()
    int i,n,j;

    //Reads number of columns from user

    cout<<"Enter value of n : "<<endl;
    cin>>n;

    //Prints the upper half part of the pattern
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=i; j++)
        {
            cout<<"*";
        }
        cout<<endl;
    }

    //Prints the lower half part of the pattern
    for(i=n; i>=1; i--)
    {
        for(j=1; j<i; j++)
        {
            cout<<"*";
        }
        cout<<endl;;
    }

    return 0;
}