【问题标题】:Random array gives invalid output after first element [C]随机数组在第一个元素后给出无效输出 [C]
【发布时间】:2018-04-09 01:59:12
【问题描述】:

我正在制作一个简单的程序,该程序可用作具有随机生成数字的热/冷猜谜游戏(输入猜测,告诉您更高或更低,重复直到猜出正确的数字。)我遇到了一些障碍随机数生成,我可以创建的最佳解决方案是生成一个包含 1000 个随机数的数组。

第一次玩游戏使用数组生成的第一个随机数,但是,第一次游戏之后的任何时间都使用4040作为随机数,而不管可能的随机数范围如何(应该是1-100正常难度设置)。我尝试以多种方式诊断问题,但我相信这个问题太难解决了,因为我对编程的经验很少(我仍在学习我的第一门编程课程),所以任何帮助找出问题将不胜感激。

相关部分代码:

int main()
{
    int randomArray[1000];
    int randomNum;
    int e=0; //element of each array
    int input, score;
    time_t t;
    char level='n', mode;

    //srand ( time(NULL) );
    srand((unsigned) time(&t));

    do
    {
        game();
    }
    while(level!='!');

    return 0;
}

void game()
{
    int randomArray[1000];
    int randomNum;
    int input;
    char level;

    printf("Chose difficulty (? for help, ! to quit): \n");
    printf("Normal (N)\n");
    printf("Medium (M)\n");
    printf("Hard (H)\n");
    printf("Impossible (I)\n");
    scanf("%c", &level);

    if(level=='N' || level=='n')
    {
        randomNum=rngNormal();
    }
    if(level=='M' || level=='m')
    {
        randomNum=rngMedium();
    }
    if(level=='H' || level=='h')
    {
        randomNum=rngHard();
    }
    if(level=='I' || level=='i')
    {
        randomNum=rngImpossible();
    }
    if(level=='?')
    {
        printf("Normal: generates random number from 1-100\nMedium: generates random number from 1-500\n");
        printf("Hard generates random number from 1-1,000\nImpossible: generates random number from 1-32,767");
    }

    getche();
    system("cls");
    printf("RANDOM NUMBER: %d\n", randomNum);//added for testing purposes
    input=load();
    while(input!=randomNum)
    {
        compare(input, randomNum);
        input=load();
     }
     compare(input, randomNum);

    return 0;
}

int rngNormal()
{
    int randomArray[1000];
    int randomNum;
    time_t t;
    int e=0;

    //generates random array
    if(e==0)
    {
        for(int a=0; a<1000; a++)
        {
            randomArray[a]=rand()%100+1;
        }

        for(int x=0; x<1000; x++)//added for testing purposes
        {
            printf("%3d ", randomArray[x]);
        }
    }

    randomNum=randomArray[e];

    e++;

    return randomNum;
}

【问题讨论】:

    标签: c arrays random


    【解决方案1】:

    你有很多问题,我会尝试列出一些:

    1. int randomArray[1000]; 每次在函数中定义时都会被多次定义,您将创建数组的本地副本 - 尽管它们具有相同的名称,但它们完全不相关
    2. 你从void函数void game() ... return 0;返回一个值
    3. level 不是全局值 - 因此当您在 game 中更改它时,它不会影响在 main 中检查的值
    4. 我无法理解使用 randomArray[1000]; 背后的任何逻辑 - 你可以生成一个随机数并猜测它有什么意义 - 为什么你需要生成 1000 个?你没有以任何方式使用它们 - e 是本地的,所以你从函数 randomArray[0] 每次返回 - 其余的在函数结束时被丢弃

    我确实建议调试,查看 C 中的局部\全局变量,您似乎误解了这些是如何实现的。我建议先构建一个没有函数的更简单的应用程序 - 调试起来会更简单,在您了解逻辑后,您可以开始将代码部分导出到函数。希望这会有所帮助..

    【讨论】:

    • 建议将-Wshadow 作为编译器选项添加到您的默认编译字符串中,以在变量被隐藏时发出警告。
    【解决方案2】:

    你在main()game() 之间影响randomArray, randomNum, input, level。更改其中一个值对另一个没有影响。使-Wshadow 成为您在编译时使用的标准选项,以便编译器会警告您该问题(如果您使用的是VS(例如cl.exe,则使用/Wall/W3)。不要隐藏变量,通过它们作为函数的参数并返回正确的值(或将指针传递给变量的 地址——因此任何更改都可以在调用函数中看到)

    while(level!='!');始终测试TRUE,因为从main() 中的初始化点(例如char level='n')开始,该值永远不会更改。

    您显然是在没有启用警告的情况下进行编译(或者您选择忽略它们)。始终在 gcc/clang 上使用至少 -Wall -Wextra -pedantic 进行编译,在 VS 上使用 /W3 进行编译。阅读并理解每个警告,并且在没有警告的情况下编译之前不要接受代码(您可以在 VS 上使用/wXXXX 来禁用与您的代码无关的警告,其中XXXX 是与您希望的特定警告相关联的代码禁用)

    scanf ("%c", ...) 将读取一个字符而留下所有其他字符(包括在输入缓冲区中按 Enter 生成的'\n'。您必须考虑它并将其删除,然后再尝试再次读取或scanf ("%c", ....) 很高兴将 uread '\n' 作为您的下一个输入。更好的输入方法是使用 fgets,它将读取并在其填充的缓冲区中包含尾随 '\n',以确保您不会陷入scanf 没有考虑到它的陷阱。

    不要使用getche() 进行输入或保持终端窗口打开。 conio.h 头文件 100% 不可移植到 Windows 以外的任何地方。请改用getcahr()cls 也很可疑(出于同样的原因)

    您尚未提供load();compare() 的定义,因此我们无法提供帮助。您不能从 game() 返回值。它被声明为void 类型并且不返回任何内容。此外,在函数结束时根本不需要return——这是自动发生的。如果您需要在void 函数中返回eariler,只需使用单词return;

    rngNormal() 有类似的阴影错误。由于上述原因,您用for(int a=0; a&lt;1000; a++) 填充randomArray[a] 不会影响main() 中的randomArray。您没有显示对rngNormal() 的调用,因此无法判断您是否正确使用了返回。

    所有这些都是基本的编码错误。花点时间找出你需要从main() 传递给你的函数的值,然后为每个传递值的函数创建一个适当的参数列表。启用编译器警告并且在编译没有错误之前不接受代码。

    如果您需要更多帮助,请编辑您的问题,在您的原始问题下方添加任何更新的代码,我们很乐意为您提供进一步的帮助。

    【讨论】:

      猜你喜欢
      • 2015-03-08
      • 1970-01-01
      • 2020-03-12
      • 2015-08-19
      • 2021-09-14
      • 2019-06-25
      • 2019-11-29
      相关资源
      最近更新 更多