代码完成,但创建了一个无限循环?

Code complete, but creates an infinite loop?

我正在尝试打印如下所示的图案,我的代码 运行 没有错误,但它会生成一个无限循环,我不确定为什么;

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

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

#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

在你的主体中试试这个

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;
}

您的 star() 函数在带有注释 "increase * by one" 的行上调用自身,这意味着它是一个递归函数。但是终止条件被打破了

您使用 char 类型的 starShape 参数初始化了一个 ASCII 值为 42 的文字 '*'。但是您实际上并没有使用它作为符号,而是使用它作为符号使用本地字符串变量 shape 进行打印。你把 starShape 当作一个计数器,你试图用它来结束循环。但它从 42 开始,只会从那里上升,所以它永远不会等于您传入的值 30。

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

传入 0
#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, 0); // function print for the amount of stars and the shape

    return 0;
}//end main

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

你把starShape的值设为*,*的ascii值为42,所以你的代码不符合代码:

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

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

您的变量用法不正确。此外,您的递归终止点的放置是有问题的(在这种情况下,由于以前不正确的变量使用而无效)。最后,您将使用预增量直接增加本地 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');
}

您可以采用该效用函数并将其用于上述 任一 算法,它会起作用。

最后,上面 all 的参数是 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);
}

输出

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