猜数字游戏就是系统随机生成一个数字,我们来猜的游戏。
这里我们约定 1表示玩游戏,0表示退出游戏。
那么怎么才能让系统随机生成一个数字呢?这里我们想到一个函数:rand()函数。
通过查阅MSDN软件我们可以看到rand()函数是一个返回值为int型的无参函数 ,而其返回的是0到RAND_MAX的一个随机整数。
那么RAND_MAX是多大呢?
在编程软件如VS2013中查看RAND_MAX的定义我们可以看到其是一个十六进制数
将0x7fff通过程序员计数器转化为十进制得32767
那么此时我们知道rand()函数返回的是0到32767的一个随机整数。此时系统随机生成数字的难题解决了。可是会发现该函数返回的整数可以大到上万,无疑猜数字的时候会有很大困难。
为了让猜数字游戏变得简单有趣,我们可以让其产生0到100的随机数。那么怎么才能让rand()函数产生0到100的随机整数呢?
可以发现让rand()函数直接产生0到100的整数是不可能的。又因为任何一个数除以100的余数总是在0到99之间,所以只要让rand()的返回值模上100,便可随机产生0到100的整数。
此时通过下述代码将系统生成的随机整数打印出来我们可以发现,生成的整数确实是随机的。但是当再一次运行程序的时候,我们会惊讶地发现此次运行程序所生成的随机数跟上一次运行程序所生成的随机数一模一样。这是为什么呢?
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>
void menu()
{
printf("********************************\n");
printf("********** 1. play ***********\n"); //输入1,表示玩游戏
printf("********** 0. exit ***********\n"); //输入0,表示退出游戏
printf("********************************\n");
}
int main()
{
int input = 0;
do{
menu(); //打印菜单
printf("请选择:");
scanf("%d", &input);
int ret = rand() % 100;
switch (input)
{
case 1:
printf("%d\n", ret); //打印生成的随机整数
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
system("pause");
return 0;
}
这是因为在调用rand()函数前,我们并没有设置随机生成的开始点。所以在调用rand()函数前,我们应该使用srand()函数设置随机生成数的开始点。那么srand()函数又是什么函数呢?
再次查阅MSDN软件我们可以知道srand()函数是一个无返回值的参数为无符号整数的一个函数,其作用就是设置一个随机数的开始点。那么只要该函数的参数在变化,便可达到生成随机数的效果。
所以现在需要做的就是给srand()函数传一个时刻在变化的参数。我们发现电脑上的时间一直在改变,用它作为该函数的参数刚好合适。那么此时又引出了一个时间函数--->time()函数
可以发现time()函数是一个返回值为time_t类型的参数为指针类型的函数,其作用就是返回系统时间。
那么time_t类型又是什么类型呢?再次将其转到定义我们可以发现time_t是一个__time64_t类型,而__time64_t又是一个整型。
所以time()函数返回的是当前程序执行时的时间点与计算机起始时间(1970年1月1日零时零分零秒)之间的差值。将该差值作为srand()函数的参数时需要将其强转成unsigned int类型。此时由于我们只关心time()函数的返回值,而并不在意其参数,所以可以将time()函数的参数设置为一个空指针(NULL)。
到这里我们便可以调用srand()函数和rand()函数了。
srand((unsigned int)time(NULL)); //设置随机生成数的开始点
rand()%100; //生成随机数
但是此时如果执行下述代码我们会发现,其实生成的随机数并不是那么随机。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void menu()
{
printf("********************************\n");
printf("********** 1. play ***********\n");
printf("********** 0. exit ***********\n");
printf("********************************\n");
}
int main()
{
int input = 0;
do{
menu();
printf("请选择:");
scanf("%d", &input);
srand((unsigned int)time(NULL));
int ret = rand() % 100;
switch (input)
{
case 1:
printf("%d\n", ret);
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
system("pause");
return 0;
}
这是因为每玩一次游戏都会重新设置一次随机生成起点,导致每次生成的起点都很接近。如果在程序执行时只设置一次随机生成起点,此时生成的随机数便会更随机。所以将srand()函数放在do{}while();循环之前便可实现。具体实现代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <windows.h>
#include <time.h>
//猜数字游戏(0-100)
void game()
{
int ret = rand()%100; //rand():返回0到0x7FFF中的整数
int cmp = 0; //用户猜的数字
while (1)
{
printf("请猜数字:");
scanf("%d", &cmp);
if (cmp > ret)
{
printf("猜大了\n");
}
else if (cmp < ret)
{
printf("猜小了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
}
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);
system("pause");
return 0;
}