完整教程:C语言——猜数字游戏(rand、srand、time函数学习)

练/学前预警:

  • 我们前面学习了C语言的选择、循环结构,以及操作符等知识,如果有忘记的知识可以打开这个链接进行学习 C语言学习专栏
  • 我们掌握了前面的知识后,我们可以做一个小游戏——猜数字游戏
  • 猜数字游戏的要求:
    • 生成1-100的随机数
      • 随机数生成需要学习(rand、srand、time)这三个函数
      • rand:生成随机数
      • srand:设置种子
      • time:得到时间戳,变化种子
    • 循环来进行猜测随机数(循环结构
    • 判断猜测的数字和随机数的大小(选择结构
    • 如果将代码都写到main函数中会看着不太清晰,所以我们可以通过函数定义、声明、调用来进行优化代码
      函数定义、声明、调用学习

猜数字游戏要求:

  • 电脑自动生成1-100的随机数;
  • 用户进行猜数字,我们根据猜测数据的大小电脑提示时大了还是小了,直到猜到,游戏结束
  • 从这个要求中我们可以提炼我们需要准备的内容:
    • 随机数的生成(rand)
    • 循环猜数字直到结束(while、for、do … while)

准备内容:

在我们前面的学习中我们并没有学习随机数的生成,那么怎么样才可以让计算机自动的生成随机数呢?

  • C语言提供了一个函数rand(),这个是可以生成随机数的(生成的是伪随机数)

1️⃣rand函数

在C语言中的标准库中提供了这个函数,详细介绍可以打开这个链接来进行学习,rand函数参考
函数原型:int rand(void);

  • rand函数是会返回一个伪随机数 ( 整数 )
    • 伪随机数: 看起来是随机的,但实际上是通过一个确定的、复杂的数学公式从一个初始的“种子”值计算出来的序列。只要种子相同,生成的序列就完全相同。
  • rand函数生成的随机数的范围是在0~RAND_MAX之间,最大随机数是依赖我们的编译器的,目前大部分的最大随机数是32767
  • rand函数的使用是需要头文件<stdlib.h>

1.1、如何知道最大随机数

  • 如果想知道目前你所使用的编译器中最大随机数是多大,可以通过这段代码来进行查阅:
#include <stdio.h>
  #include <stdlib.h> // 包含 rand() 和 RAND_MAX 的定义
    int main()
    {
    printf("RAND_MAX 的值是: %d\n", RAND_MAX);
    return 0;
    }
    //我的运行得到是 32767

1.2、rand函数的使用代码

  • 通过下面这个代码运行我们可以得到下面的结果
#include <stdio.h>
  #include <stdlib.h> // 包含 rand() 和 RAND_MAX 的定义
    int main()
    {
    printf("1、%d\n", rand());
    printf("2、%d\n", rand());
    printf("3、%d\n", rand());
    printf("4、%d\n", rand());
    return 0;
    }

在这里插入图片描述

  • 我们通过两次的运行结果对比可以知道,
  • 每次的运行中只是相对于当次的四个数是相对随机的
  • 但多次运行可以知道,这并不随机

这是为什么呢?

  • 是因为rand函数是生成伪随机数,这是通过某种算法生成的随机数
  • rand函数是通过 “种子” 为标准来进行运算生成的随机数
  • 每次运行的随机数的序列相同是因为rand函数生成随机数的默认种子为 1
  • 并不是真正的随机数,真正的随机数是无法预测下一刻的值会是多少的
  • 既然rand函数是默认种子为1,我们可不可以通过变化种子来进行生成真正的随机数

显而易见,这是必然可以的,下面我们学习srand()函数和time()函数变化种子来生成随机数

2️⃣srand函数

  • C语言中提供了一个函数srand()这个是用来初始化随机数的生成器,这个函数也需要<stdlib.h>头文件
  • srand原型:void srand(unsigned int seed)
  • 程序在使用rand()时,我们可以先调用srand()通过设置参数seed的值,来进行设置rand()函数生成随机数的种子。
    • 只要种子发生变化,生成的随机数序列也是随机的(下面有体现)

使用:

#include<stdio.h>
  #include<stdlib.h>
    int main()
    {
    srand(3);
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    return 0;
    }

如果我们改变srand()函数里面的值会怎么样呢?

在这里插入图片描述

  • 所以我们只要将srand()的种子是随机变化的,rand()就可以生成真正的随机数

我们应该如何将种子随机变化,让种子变成随机数呢?
这个学习参考链接有对C语言的函数进行说明
srand参考
在这里插入图片描述

为了生成类似随机数的 , srand 通常初始化为一些独特的运行时值,例如函数 time 返回的值

  • 所以我们可以通过time函数来进行对种子的变化

3️⃣time函数

  • 我们将时间作为种子是因为时间是时时刻刻在变化的
  • 在C语言中time函数就可以获得这个时间,使用这个函数需要头文件<time.h>
  • time参考
    在这里插入图片描述
    • 如果 timer为 NULL,则函数会把结果 (返回时间值) 同时保存到 *timer 中 (该指针指向的内存中)

    • 如果 timer为 NULL,只返回时间值,不保存

    • 我们可以根据下面的代码,大致了解上面的意思,根据自己的需要来进行使用

time_t t1;   // 定义一个 time_t 类型变量
time_t t2;	 // 定义一个 time_t 类型变量
time(&t1);         // 把当前时间保存到 t1 中
t2 = time(NULL);   // 获取时间返回值,不保存到任何变量(NULL表示不保存)
  • time 函数原型:time_t time (time_t* timer);
    • 这个函数会返回从现在程序运行时间到1970年1月1日0时0分0秒的差值(秒)
    • 返回类型是time_t,这个是32位或64位的整型类型
  • time函数返回的时间差也叫时间戳
    时间戳的转换

4️⃣随机数生成代码

现在我们已经学习了三个函数,我们可以将真正的随机数的代码写出来了

  • srand()函数在 程序运行时,只需要设置一次随机种子;
    • 之后的每次 rand() 调用,都会根据上一次的状态自动生成新的 “ 伪随机数 ” ,每次运行程序都会不一样(因为时间不同)
  • srand()函数反复调用,则可能导致time(NULL) 在同一秒内的值是一样的,所以每次种子都一样 → 随机序列也一样 → 看起来“不随机”
#include<stdio.h>
  #include<stdlib.h>	//srand,rand
    #include<time.h>	//time
      int main()
      {
      //使用time函数的返回值设置种子
      // time(NULL)
      //srand的函数原型是:void srand(unsigned int seed)
      //因为srand的参数类型unsigned int,所以我们需要将time强制类型转换
      srand((unsigned int)time(NULL));
      printf("%d\n", rand());
      printf("%d\n", rand());
      printf("%d\n", rand());
      printf("%d\n", rand());
      return 0;
      }
      **********************************
      输出:
      27781
      11507
      3142
      18474
  • 以上的输出是我的电脑运行时的输出结果,我们可以看到这个随机数太大了,我们可以限制随机数的范围,来生成随机数

5️⃣随机数的范围控制

  • 生成[a, b]范围的整数rand() % (b - a + 1) + a
    • 需要注意这个运算顺序先算括号的,再取余,再加法
  • 生成[a, b]范围的浮点数(double)rand() / RAND_MAX * (b - a) + a

为什么rand函数的返回值是整数却又浮点型的随机数呢?

  • rand函数原型:int rand(void);
  • 理应来说,应该是只生成整型的随机数
  • 浮点随机数是人为“转换”出来的。
    • 先通过这个得到[0.0,1.0]范围的浮点数,(double)rand() / RAND_MAX;
    • 再乘上想要的范围,得到了随机范围的浮点数,(double)rand() / RAND_MAX * (b - a) + a

因为在很多应用中,我们不只是需要整数的随机性,所以人为界定了浮点型随机数

  • 代码实现:
#include<stdio.h>
  #include<stdlib.h>	//srand,rand
    #include<time.h>	//time
      int main()
      {
      //要0-100的随机数
      srand((unsigned int)time(NULL));
      int arr[3] = { 0 };//初始化数组
      for (int i = 0; i < 3; i++)
      {
      arr[i] = rand() % 101;
      printf("%d\t", arr[i]);
      }
      return 0;
      }
      ****************
      输出:
      80      46      4

猜数字游戏代码:

我们已将将这个C语言代码的准备工作已经准备好了,下面我们就可以正式开始写这个代码了

  • 知识储备:
    • 循环猜数字,直到正确为止(for、while、do while
    • 随机数(rand、srand、time

1.1、设置游戏菜单

  • 只在最开始时判断是否要玩游戏,最开始问一次和最后猜对数字后再问一次是否开始游戏
  • 输入1是开始玩游戏;输入0则是退出游戏
int main()
{
printf("***********************************\n");
printf("************1. play game************\n");
printf("************2. exit game************\n");
printf("***********************************\n");
}

1.2、设置游戏

  • 生成[1,100] 的随机数
  • 输入用户所猜测的数字
  • 根据用户猜的数字和生成的随机数比较并提供提示
  • 直到用户猜到正确数字停止游戏
int main()
{
int guess= 0;			//用户猜测数字
srand((unsigned int)time(NULL));
int r = rand() % 100 + 1;		//生成1-100的随机数
while(1)
{
printf("请输入猜测的数字:");
scanf("%d", &guess);
if (guess > r)
printf("猜大了!\n\n");
else if (guess < r)
printf("猜小了!\n\n");
else
{
printf("太厉害了,猜对了!\n\n");
break;
}
}
}

1.3、代码总体实现

#include<stdio.h>
  #include<stdlib.h>	//srand,rand
    #include<time.h>	//time
      int main()
      {
      int input = 0;
      do
      {
      printf("***********************************\n");
      printf("************1. play game************\n");
      printf("************0. exit game************\n");
      printf("***********************************\n");
      printf("请选择》》");
      scanf("%d", &input);
      switch (input)
      {
      case 1:
      {
      int guess = 0;			//用户猜测数字
      srand((unsigned int)time(NULL));
      int r = rand() % 100 + 1;		//生成1-100的随机数
      while (1)
      {
      printf("请输入猜测的数字:");
      scanf("%d", &guess);
      if (guess > r)
      printf("猜大了!\n\n");
      else if (guess < r)
      printf("猜小了!\n\n");
      else
      {
      printf("太厉害了,猜对了!\n\n");
      break;
      }
      }
      break;
      }
      case 0:
      {
      printf("游戏结束!\n");
      break;
      }
      default:
      {
      printf("选择错误,请重新选择!\n");
      break;
      }
      }
      } while (input);
      return 0;
      }

优化猜数字游戏代码(通过函数声明 、定义、调用)

我们可以看到上面的代码非常的乱,可读性很低


  • 菜单栏:
void menu()
{
printf("***********************************\n");
printf("************1. play game************\n");
printf("************0. exit game************\n");
printf("***********************************\n");
}
  • 游戏栏:
void game()
{
int guess = 0;			//用户猜测数字
srand((unsigned int)time(NULL));
int r = rand() % 100 + 1;		//生成1-100的随机数
while (1)
{
printf("请输入猜测的数字:");
scanf("%d", &guess);
if (guess > r)
printf("猜大了!\n\n");
else if (guess < r)
printf("猜小了!\n\n");
else
{
printf("太厉害了,猜对了!\n\n");
break;
}
}
}
  • 总体实现:
#include<stdio.h>
  #include<stdlib.h>	//srand,rand
    #include<time.h>	//time
      //菜单
      void menu()
      {
      printf("***********************************\n");
      printf("************1. play game************\n");
      printf("************0. exit game************\n");
      printf("***********************************\n");
      }
      //猜数字游戏
      void game()
      {
      int guess = 0;			//用户猜测数字
      srand((unsigned int)time(NULL));
      int r = rand() % 100 + 1;		//生成1-100的随机数
      while (1)
      {
      printf("请输入猜测的数字:");
      scanf("%d", &guess);
      if (guess > r)
      printf("猜大了!\n\n");
      else if (guess < r)
      printf("猜小了!\n\n");
      else
      {
      printf("太厉害了,猜对了!\n\n");
      break;
      }
      }
      }
      //主函数
      int main()
      {
      int input = 0;
      do
      {
      menu();
      printf("请选择 》");
      scanf("%d", &input);
      switch (input)
      {
      case 1:
      game();
      break;
      case 0:
      printf("游戏结束!\n");
      break;
      default:
      printf("选择错误,请重新选择!\n\n");
      break;
      }
      } while (input);
      return 0;
      }

猜数字游戏升级(限制猜测次数)

我们可以设置一个计数器,
计算用户猜测次数,
当用户猜测次数达到5次,则自动判断猜数字失败;
并且进入重新选择是否开始猜数字游戏的界面

#include<stdio.h>
  #include<stdlib.h>	//srand,rand
    #include<time.h>	//time
      //菜单
      void menu()
      {
      printf("***********************************\n");
      printf("************1. play game************\n");
      printf("************0. exit game************\n");
      printf("***********************************\n");
      }
      //猜数字游戏
      void game()
      {
      int count = 0;		//计数器
      int guess = 0;			//用户猜测数字
      srand((unsigned int)time(NULL));
      int r = rand() % 100 + 1;		//生成1-100的随机数
      while (count<5)
      {
      printf("请输入猜测的数字:");
      scanf("%d", &guess);
      count++;
      if (guess > r)
      {
      printf("猜大了!\n");
      printf("猜测次数还剩:%d\n\n", 5 - count);
      if (count == 5)
      {
      printf("猜测次数用完,再接再厉!\n\n");
      }
      }
      else if (guess < r)
      {
      printf("猜小了!\n");
      printf("猜测次数还剩:%d\n\n", 5 - count);
      if (count == 5)
      {
      printf("猜测次数用完,再接再厉!\n\n");
      }
      }
      else
      {
      printf("太厉害了,猜对了!\n\n");
      break;
      }
      }
      }
      //主函数
      int main()
      {
      int input = 0;
      do
      {
      menu();
      printf("请选择 》");
      scanf("%d", &input);
      switch (input)
      {
      case 1:
      game();
      break;
      case 0:
      printf("游戏结束!\n");
      break;
      default:
      printf("选择错误,请重新选择!\n\n");
      break;
      }
      } while (input);
      return 0;
      }

✒️小结:

  • 我们前面学习了rand、srand、time函数
  • 学习了函数声明、定义、调用来进行函数的优化
  • 猜数字游戏的二次优化(限制猜测次数)

感谢大家的浏览

posted @ 2025-12-13 15:02  yangykaifa  阅读(1)  评论(0)    收藏  举报