c++ 星号的意外输出

7jmck4yq  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(74)
#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{

    int num;
    int y [11];

    cout << "Enter the amount of numbers you would like generated: " << endl;
    cin >> num;
    cout << endl;

    int x[num];

    for (int j=0; j<=num; j++)
    {
        x[j]=(rand()%10)+1;
    }

    for (int j=0; j<=num; j++)
    {
        switch (x[j])
        {
            case 1:
            y[1]+=1;

        }

    }

    for (int a=0;a<=y[1]+1; a++)
    {
        switch (a)
        {
            case 0:
            cout << "1: ";
            break;

            default:
            cout << "*";
        }

    }
}

字符串
这个程序的目的是在数组中每次出现数字1时打印一个星号。但是,输出的是无限多的星号。

piztneat

piztneat1#

你的代码有很多问题。最重要的是,你的循环超出了你的x数组的范围,所以第一个循环正在破坏周围的内存。而且你没有初始化y[1],所以它将有一个随机值,然后你的第二个循环递增。这可能是为什么你在输出中看到这么多 Flink 的原因-y可能从一个大值开始开始。
尝试类似这样的东西:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int num;
    int y = 0;

    cout << "Enter the amount of numbers you would like generated: " << endl;
    cin >> num;
    cout << endl;

    vector<int> x(num);    

    srand(time(0));

    for (int j = 0; j < num; ++j)
    {
        x[j] = (rand() % 10) + 1;
        if (x[j] == 1)
            ++y;
    }

    cout << "1: ";
    for (int a = 0; a < y; ++a)
        cout << "*";
    cout << endl;

    return 0;
}

字符串
可以通过完全消除xy来简化:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int num;

    cout << "Enter the amount of numbers you would like generated: " << endl;
    cin >> num;
    cout << endl;

    cout << "1: ";
    for (int j = 0; j < num; ++j)
    {
        if ((rand() % 10) == 0)
            cout << "*";
    }
    cout << endl;

    return 0;
}


没有理由为y使用数组,因为你只是白白浪费了11个插槽中的10个。只有当你实际跟踪多个计数器时,使用数组才更有意义:

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int num, x;
    int y[10] = {};

    cout << "Enter the amount of numbers you would like generated: " << endl;
    cin >> num;
    cout << endl;

    for (int j = 0; j < num; ++j)
    {
        x = rand() % 10;
        y[x]++;
    }

    for (int a = 0; a < 10; ++a)
    {
        cout << a+1 << ": ";
        for (int b = 0; b < y[a]; ++b)
            cout << "*";
        cout << endl;
    }

    return 0;
}

eh57zj3b

eh57zj3b2#

你的原始代码与无关的变量纠缠在一起,包括不属于C++标准的C功能,并以多种方式调用未定义的行为。在代码中使用尽可能多的变量来存储各种值没有什么错,但是考虑你需要什么并限制你跟踪的不同值的数量可以帮助你保持代码逻辑在正确的轨道上。看看你的整数数组y

int y [11];

字符串
y声明为11 * 未初始化元素 * 的数组。在声明时,y中的每个元素都是不确定的(意味着每个只包含随机垃圾值),任何在y的元素初始化之前访问它的尝试都会调用 Undefined Behavior --如果声明为int,则每个元素中保存的不确定值的范围可以从-2147483648 to 2147483647(4字节整数值的范围)
当你生成一个可以被10整除的随机值时,你可以执行:

y[1]+=1;


也就是y[1] = y[1] + 1;,但问题是y[1]在这一点上是不确定的,它可以是任何东西,你刚刚调用了未定义的行为,你的代码可以做任何事情,从看起来行为正确--或者SegFault。
继续,你的下一个声明是:

int x[num];


这是C * 可变长度数组 *(VLA)的声明。VLA是C标准不允许的,但作为Gnu扩展提供,例如-std=gnu++11。如果你没有使用提供VLA的扩展,你的代码甚至不应该编译。即使你使用提供VLA的扩展,你的编译器应该警告你它不是C标准的一部分。
如果你想使用一个未知长度的数组,那么动态分配x

int *x = new int[num];


然后你就有了存储空间来保存一个num整数数组。(当delete[] x;不再需要时,你应该释放内存)
不管你如何分配x,正如所指出的,然后你尝试读取超过x的结尾:

for (int j=0; j<=num; j++)


数组的索引从0n-1,因此使用for (int j=0; j<num; j++)控制每个元素的迭代的正确for循环条件
如果我正确地阅读了您的代码,那么您只是尝试在每次生成可被10整除的随机数时输出并检查"*"。虽然不需要,但您尝试将可被10整除的随机数存储在y[1]中(受上面提到的未初始化问题的影响)。通过使用未初始化的y[1],它可以保存像2147483647一样大的垃圾值,或者甚至是表示二进制中的负数的值,所以y[1] += 1;可以是任何值,甚至是负数。
然后循环for (int a=0;a<=y[1]+1; a++),你可能会循环0次,或者你可能会在屏幕上多次填充空格。
此外,尽管您可以自由地使用任意多的变量来独立地跟踪每个值,(直到可用的堆栈和可用的系统存储器),声明int y[11];然后只使用数组y[1]中的第二个元素没有太大意义。你根本不需要数组。如果你只是想在生成的值可整除时输出一个空值,通过10,你甚至不需要一个x。你所需要的只是你想生成的随机数的数量。如果你重构并将你的代码配对到最小,你可以写一些更短的东西来完成这项工作,类似于:

#include <iostream>
#include <cstdlib>

using namespace std;

int main (void) {

    int num;
    
    srand (time(NULL)); /* seed random number generator */
    
    cout << "Enter the amount of numbers you would like generated: ";
    if (!(cin >> num)) {    /* validate integer input */
        cerr << "error: invalid input.\n";
        return 1;
    }

    cout << "\n1: ";
    for (int j = 0; j < num; j++)       /* loop num times */
        if (rand() % 10 == 0)           /* divisible by 10? */
            cout << "*";                /* output asterisks */
    
    cout << '\n';   /* output POSIX compliant newline at end */
}

示例使用/输出

$ ./bin/asterisks_min
Enter the amount of numbers you would like generated: 20

1: ****


但是,如果您确实想存储测试生成的随机数是否可被10整除的10结果序列,则可以简单地按照上面的讨论分配x,并根据测试(rand() % 10 == 0)的结果填充值。为了验证逻辑,您可以输出rand % 10的结果,和存储在x[j]中的值,以确认您输出的是正确的扫描次数。
只需要对变量进行一点调整,并将不必要的switch()语句替换为简单的if子句,您就可以完成与最初尝试的内容接近的操作,例如。

#include <iostream>
#include <iomanip>
#include <cstdlib>

using namespace std;

int main (void) {

    int num;
    
    srand (time(NULL)); /* seed random number generator */
    
    cout << "Enter the amount of numbers you would like generated: ";
    if (!(cin >> num)) {    /* validate integer input */
        cerr << "error: invalid input.\n";
        return 1;
    }

    int *x = new int[num];  /* allocate, VLA not standard in C++ */

    for (int j = 0; j < num; j++) {     /* loop num times */
        int v = rand() % 10;            /* rand mod 10 */
        if (v == 0)                     /* divisible by 10? */
            x[j] = 1;                   /* store 1 */
        else
            x[j] = 0;                   /* store 0 */
        /* debug output, rand % 10 & contents of x[] */
        cout << "v: " << v << "  ->  x[" << setw(2) << j << "]: " 
            << x[j] << '\n';
    }
    
    cout << "\n1: ";                    /* simply output prefix */
    for (int a = 0; a < num; a++)       /* then loop over stored 1's */
        if (x[a] == 1)
            cout << "*";                /* output * for each 1 value */
    cout << '\n';                       /* tidy up with newline */
    
    delete[] x;
}

示例使用/输出

$ ./bin/asterisks
Enter the amount of numbers you would like generated: 20
v: 6  ->  x[ 0]: 0
v: 9  ->  x[ 1]: 0
v: 1  ->  x[ 2]: 0
v: 1  ->  x[ 3]: 0
v: 3  ->  x[ 4]: 0
v: 8  ->  x[ 5]: 0
v: 0  ->  x[ 6]: 1
v: 3  ->  x[ 7]: 0
v: 9  ->  x[ 8]: 0
v: 8  ->  x[ 9]: 0
v: 2  ->  x[10]: 0
v: 5  ->  x[11]: 0
v: 9  ->  x[12]: 0
v: 9  ->  x[13]: 0
v: 8  ->  x[14]: 0
v: 3  ->  x[15]: 0
v: 0  ->  x[16]: 1
v: 0  ->  x[17]: 1
v: 3  ->  x[18]: 0
v: 2  ->  x[19]: 0

1: ***


如果我理解了你代码的最终目标,这就证实了你为每个能被10整除的随机值输出"*"
最后,当使用rand()时,在第一次调用rand()之前,您应该为半随机数生成器设置种子。您可以使用半唯一值,例如使用time (NULL)的epoch后的秒数,或者您可以提供一个固定的种子,以便您可以重新生成随机集以供以后使用和评估。

相关问题