我们来写个简单的小游戏:猜数字
先看流程图(建议放大)
首先,我们要了解怎么用代码生成随机数,并且约束随机数生成的范围
1.怎么生成随机数
了解之前,我们需要知道一些知识背景;
rand函数:返回一个伪随机数,该随机数范围:0~RAND_MAX(RAND_MAX大小依赖编译器实现,但大部分编译器上RAND_MAX是32767)
使用rand函数需要包含一个头文件:stdlib.h
先看该函数原型:
int rand(void);
然后,我们打印出rand函数生成的随机值,看看是不是每次生成都有所区别
#include<stdio.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;
}
我们生成两次,发现结果都一样。说明这随机序列没有随机嘛!
问题在这里:rand 函数生成的是伪随机数,伪随机数不是真正的随机数。
那为什么两次生成随机数序列一样呢:rand函数是对⼀个叫“种⼦”的基准值进⾏运算,然后⽣成的随机数。⽣成随机数的默认种⼦是1,所以每次运⾏程序产⽣的随机数序列是⼀样的。
如果要⽣成不同的随机数,就要让种⼦是变化的。
所以,看第二个函数:srand函数
srand原型:
void srand(unsigned int seed);
通过 srand 函数的参数seed来设置rand函数⽣成随机数的时候的种⼦。
种子在变化,则生成的随机数序列才变化。
给srand的种⼦是如果是随机的,rand就能⽣成随机数;
在⽣成随机数的时候⼜需要⼀个随机数,这就⽭盾了。
所以,看第三个函数time:程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的。
time原型:
time_t time (time_t* timer);
time函数其实返回的是1970年1月1日0时0分0秒到现在程序运行时间之间的差值,单位是秒。
返回的差值类型是time_t,time_t 类型本质上其实就是32位或者64位的整型类(为后面为什么要强制类型转换铺垫)。
time函数使用时需要包含头文件:time.h
我们用everything搜索time.h,可以发现time.h整型类型
从time_t time (time_t* timer);可知time函数的参数是timer。
如果timer是非NULL指针,函数返回时间差值同时,也会将返回的差值放在timer指向的内存中带回去。
如果timer是NULL(空),就只返回时间的差值,这个时间差也叫:时间戳
举例:只返回时间戳(差值),不接收返回值
time(NULL);//调用函数返回时间戳(差值),这里没有接受返回值
所以我们将代码改成:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
srand((unsigned int)time(NULL));
//因为srand函数是unsigned int类型,所以time函数返回值要强制类型转换
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
两次运行结果不一样。随机数序列随机了!!
注意:srand函数不需要频繁调用,一次运行程序调用一次就够了。
2.设置随机数范围
接下来,设置随机数范围。
1.表示范围0~99
(%100余数是0~99)
rand()%100;
//0+rand()%(99-0+1);
2.表示范围1~100(余数)
(%100余数范围+1)
1+rand()%100;
//1+rand()%(100-1+1);
3.表示范围100~200(余数)
(%101余数范围(0~100)+100)
100+rand()%101;
//100+rand()%(200-100+1);
4.总结:表示范围a~b的随机数
a+rand()%(b-a+1);
3.实现游戏
再放大看一遍流程图的思路,实现猜数字游戏:(加上猜数字的次数限制,如果5次猜不出来,就算失败)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void game()
{
int r = rand() % 100 + 1;
int guess = 0;
int count = 5;
while (count)
{
printf("请输入数字:>");
scanf("%d", &guess);
count--;
if (guess < r)
{
printf("猜小了\n");
}
else if (guess > r)
{
printf("猜大了\n");
}
else
{
printf("恭喜你,猜对了!\n");
break;
}
}
if (count == 0)
{
printf("你失败了,正确数字是:%d\n", r);
}
}
void menu()
{
printf("***********************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("***********************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束了\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
若有补充地方,后续会更新。
如果有发现不足,望各位指正,谢谢。