之前给大家讲过分支和循环,这一期我们继续将分支和循环,并且掌握了前⾯学习的这些知识,我们就可以写⼀些稍微有趣的代码,写一个小游戏-猜数字游戏
游戏要求:
1. 电脑⾃动⽣成1~100的随机数
2. 玩家猜数字,猜数字的过程中,根据猜测数据的⼤⼩给出⼤了或⼩了的反馈,直到猜对,游戏结束
随机数生成
要想完成猜数字游戏,⾸先得产⽣随机数,那怎么产⽣随机数呢?
Rand
C语⾔提供了⼀个函数叫 rand,这函数是可以⽣成随机数的,函数原型如下所⽰:
int rand (void)
注意:viod是不需要参数的意思
rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的⼤⼩是 依赖编译器上实现的,但是⼤部分编译器上是32767
注意:rand函数的使⽤需要包含⼀个头⽂件是:stdlib.h
那我们就测试⼀下rand函数,这⾥多调⽤⼏次,产⽣5个随机数:
#include <stdio.h>
#include <time.h>
#include<stdlib.h>
int main()
{
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
我们发现不管运行几次都是一样的数字
我们可以看到虽然⼀次运⾏中产⽣的5个数字是相对随机的,但是下⼀次运⾏程序⽣成的结果和上⼀次 ⼀模⼀样,这就说明有点问题 如果再深⼊了解⼀下,我们就不难发现,其实rand函数⽣成的随机数是伪随机的,伪随机数不是真正的随机数,是通过某种算法⽣成的随机数真正的随机数的是⽆法预测下⼀个值是多少的⽽rand函数是对⼀个叫“种⼦”的基准值进⾏运算⽣成的随机数
注意:之所以前⾯每次运⾏程序产⽣的随机数序列是⼀样的,那是因为rand函数⽣成随机数的默认种⼦是1 如果要⽣成不同的随机数,就要让种⼦是变化的
Srand
C语⾔中提供了⼀个函数叫 srand,⽤来初始化随机数的⽣成器的,srand的原型如下:
void srand(unsigned int seed);
程序中在调⽤ rand 函数之前先调⽤ srand 函数,通过 srand 函数的参数seed来设置rand函数⽣成随机数的时候的种⼦,只要种⼦在变化,每次⽣成的随机数序列也就变化起来了
那也就是说给srand的种⼦是如果是随机的,rand就能⽣成随机数;在⽣成随机数的时候⼜需要⼀个随机数,这就⽭盾了
Time
在程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的
在C语⾔中有⼀个函数叫 time ,就可以获得这个时间,time函数原型如下:
time_t time(time_t * timer);
time 函数会返回当前的⽇历时间,其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的差值,单位是秒返回的类型是time_t类型的,time_t 类型本质上其实就是32位或者64位的整型类型
time函数的参数 timer 如果是⾮NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带回去
如果 timer 是NULL,就只返回这个时间的差值time函数返回的这个时间差也被叫做:时间戳
注意:time函数的时候需要包含头⽂件:time.h
如果只是让time函数返回时间戳,我们就可以这样写:
time(NULL);
那我们就可以让⽣成随机数的代码改写成如下:
int main()
{
srand((unsigned int)time(NULL));
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
srand((unsigned int)time(NULL)):srand是生成种子,time为NULL表示来让time返回一个时间戳,因为time返回值是time_t,是long-long类型,而srand函数需要un int类型,所以要用强制类型转换,此时srand扩号里就是一个随机种子 注意:time中的NULL必须大写,不能小写 |
这样下来,每次运行都是随机值了,不会和前一次重复了
注意:srand函数是不需要频繁调⽤的,⼀次运⾏的程序中调⽤⼀次就够了
设置随机数的范围
如果我们要⽣成0~99之间的随机数,⽅法如下:
rand() % 100;//余数的范围是0~99
如果要⽣成1~100之间的随机数,⽅法如下:
rand() % 100 + 1;//%100的余数是0~99,0~99的数字+1,范围是1~100
如果要⽣成100~200的随机数,⽅法如下:
100 + rand() % (200 - 100 + 1)//余数的范围是0~100,加100后就是100~200
所以如果要⽣成a~b的随机数,⽅法如下:
a + rand() % (b-a+1)
猜数字游戏实现
void 菜单()
{
printf("…………………………\n");
printf("… 1:玩游戏 …\n");
printf("… 0:退出游戏 …\n");
printf("…………………………\n");
}
void 游戏()
{
int b = rand() % 100 + 1;
int c = 0;
int d = 5;
printf("\n注意:你一共有%d次机会\n", d);
printf("请猜数字(0~100):");
while (d)
{
if (d <= 4)
{
printf("\n注意:你还有%d次机会\n", d);
printf("请重新输入:");
}
scanf("%d", &c);
if (c > b)
{
printf("游戏结果:大了\n");
}
else if (c<b)
{
printf("游戏结果:小了\n");
}
else
{
printf("游戏结果:猜对了\n\n\n");
break;
}
d--;
}
if (d == 0)
{
printf("游戏失败!正确的是%d\n\n\n",b);
}
}
int main()
{
int a = 0;
srand((unsigned int)time(NULL));
do {
菜单();
printf("请输入数字:");
scanf("%d", &a);
switch (a)
{
case 1:
游戏();
break;
case 0:
break;
default:
printf("\n\n请输入正确的数字\n");
}
} while (a);
return 0;
}
解释:
- void 菜单():创建一个名为菜单的函数并且用printf布局菜单
- void 游戏():创建一个名为游戏的函数,并在这里写游戏的主体
- int b = rand() % 100 + 1:创建一个整型变量b,然后用rand函数生成一个随机值,而 % 100 + 1 是将随机值100取模在+1这样随机值就固定在0~100了,将这个随机值初始化给b
- int c = 0:定一个整型变量为c,初始化为0,在后面的代码用c来存储用户猜的数字
- int d = 5:定义一个整型变量为d,初始化为5,来规定游戏的次数
- printf("\n注意:你一共有%d次机会\n", d):将游戏次数和文字打印到屏幕上
- printf("请猜数字(0~100):"):将游戏内容及规则打印到屏幕上
- while (d):用while循环来进入游戏主体,用d来判断游戏次数,直到d为0(假)就结束循环
- if (d <= 4):用if函数判断游戏次数如果小于等于4就执行下面子代码
- printf("\n注意:你还有%d次机会\n", d):将每次循环剩余的次数打印到屏幕上
- printf("请重新输入:"):将内容打印到屏幕上
- scanf("%d", &c):用scanf来接受用户输入的值,并且以十进制的方式存储到c
- if (c > b):用if判断c与b的大小,如果为真则进入子语句
- printf("游戏结果:大了\n"):将内容打印到屏幕上
- else if (c<b):如果以上if为假,则用if继续判断c与b的大小
- printf("游戏结果:小了\n"):将内容打印到屏幕上
- else:如果以上if为假,则进入子语句
- printf("游戏结果:猜对了\n\n\n"):将内容打印到屏幕上
- break:退出循环
- d--:除猜对外, 每次循环代表游戏次数的d减少一个
- if (d == 0):退出循环后,有两种结果,一种是游戏次数用完,游戏失败;另一种是猜对了游戏胜利,此if是判断游戏次数用完的情况下退出循环的,如果d=0了则执行子语句
- printf("游戏失败!正确的是%d\n\n\n",b):将内容及正确答案打印到屏幕上
- int main():进入主函数
- int a = 0:定义一个整型变量为a,在后面的代码中用来存储用户对菜单的选择的数
- srand((unsigned int)time(NULL)):srand是生成种子,time为NULL表示来让time返回一个时间戳,因为time返回值是time_t,是long-long类型,而srand函数需要un int类型,所以要用强制类型转换,此时srand扩号里就是一个随机种子
- do:进入do while循环
- 菜单():调用菜单函数
- printf("请输入数字:"):将内容打印到屏幕上
- scanf("%d", &a):用scanf来接受用户对菜单选择的值,并且以十进制的方式存入a
- switch (a):进入Switch语句,并且根据用户对菜单的选择来进入相应的case语句,如果用户选择0(假),则不加入Switch语句
- case 1:用户选择1,则进入子语句
- 游戏():调用游戏函数
- Break:退出Switch语句,如果不退出那么会执行后面的case,那么游戏就混乱了
- case 0:用户选择0,则进入子语句
- break; 退出Switch语句,如果不退出那么会执行后面的case,那么游戏就混乱了
- default:用户没有输入1和0,则进入子语句
- printf("\n\n请输入正确的数字\n"):将内容打印到屏幕上
- while (a):进入while循环,用a判断是否还要从do语句开始,如果代表用户选择的值(a)为0(假),则不再进入Switch语句
- return 0:返回整型值0给main函数
ok,到这里我们就讲完了这个猜数游戏咯,我们下期见