星号的意外输出

时间:2018-03-29 01:05:47

标签: c++

#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中出现数字1时打印星号。但是,输出是无数个星号。

2 个答案:

答案 0 :(得分:1)

您的代码存在多个问题。最重要的是,你的循环超出了x数组的范围,因此第一个循环会破坏周围的内存。并且您没有初始化y[1],因此它将具有随机值,您的第二个循环然后递增。这可能是您在输出中看到如此多星号的原因 - 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;
}

答案 1 :(得分:0)

很多时候,您在StackOverflow上获得的响应与您提出问题的方式直接相关(请参阅:How to Ask a Question)。也就是说,通常可能存在语言障碍等。这部分隐瞒了您在问题中所付出的努力或问题的确切性质。花点时间阅读上面的链接并努力提出你的问题,以便这里的人们更容易帮助你解决你正在努力解决的具体问题。

您的原始代码与无关的变量纠缠在一起,包括不属于C ++标准的C功能,并以多种方式调用未定义的行为。使用尽可能多的变量来存储代码中的各种值没有任何问题,但是考虑您需要的内容并限制您跟踪的不同值的数量可以帮助您保持代码逻辑的正常运行。让我们首先看一下你的整数数组y

int y [11];

y声明为11 未初始化元素的数组。在声明时,y中的每个元素都是不确定的(意味着每个元素只包含随机垃圾值),并且在初始化之前访问y元素的任何尝试都会调用未定义的行为 - 您可以毫不自信地从那时起您的代码将正确行事。声明为int,每个元素中保存的不确定值的范围可以是-2147483648 to 2147483647(4字节整数值的范围)

当您生成可被10整除的随机值时,执行:

y[1]+=1;

哪个是y[1] = y[1] + 1;。然而问题是y[1]在这一点上是不确定的,它可能是任何东西,你刚刚调用了未定义的行为,并且你的代码可以做任何事情从看似行为正确 - 或SegFault。

继续,您的下一个声明是:

int x[num];

这是C 可变长度数组(VLA)的声明。 C ++标准不允许VLA,但作为Gnu扩展提供,例如-std=gnu++11。如果您没有使用提供VLA的扩展,则您的代码甚至不应该编译。即使您使用的是提供它们的扩展,您的编译器也应警告您它不是C ++标准的一部分。

如果要使用未知长度的数组,请使用以下内容为x动态分配:

int *x = new int[num];

然后,您可以使用存储来保存num整数数组。 (你应该在delete[] x;不再需要时释放内存)

正如所指出的那样,无论你如何为x分配,你都会尝试在x的末尾阅读:

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

数组从0索引到n-1,因此使用for

来控制每个元素的迭代的正确for (int j=0; j<num; j++)循环条件

如果我正确阅读了您的代码,那么每次生成一个可被"*"整除的随机数时,您只是尝试输出和星号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。您所需要的只是您希望生成的randoms数量。如果你重构并将你的代码配对到最低限度,你可以编写一些更短的代码来完成这项工作,类似于:

#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结果来测试生成的random是否可以被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)的纪元以来的秒数,或者您可以提供一个固定的种子,允许您重现随机集以供以后使用和评估。

仔细看看,如果您有任何疑问,请告诉我。虽然你的问题并不完全清楚,而且你的代码有点混乱 - 那些通常是需要最多帮助的问题。