C语言随机数的生成
C语言生成随机数需要3个函数配合,分别是rand
、srand
、和time
。对应的头文件是stdlib.h
(rand
和 srand
)与time.h
(time
)。
rand函数
rand
函数会生成上限为32767的伪随机数。叫做伪随机数的原因是如果仅仅使用rand,每次运行程序得到的随机数都是一样的。因此rand
函数需要配合下面的函数进行使用。
srand函数
srand
函数是作为rand
函数的种子存在的。rand
函数会根据srand
的数值生成随机数,如果没有srand
函数,rand
函数的种子被固定为1。srand
需要使用一个随机数作为输入来产生一个随机的种子。这里就有矛盾了。实际使用中,并不需要真正的随机数,仅需要一个变化的量就可以了。
time函数
time
会返回起始时刻(1970/1/1 00:00:00)到当前时刻的时间差(以秒计算,不考虑润秒)。time
函数的参数如果是NULL
,那么会直接返回秒差。由于时间是不断变化的,因此time
的返回值可以作为srand
的参数,生产“随机”的种子,然后再被rand
调用。这里还涉及一些强制类型转换:
srand((unsigned int)time(NULL));
rand();
由于程序每次运行时,时间都不一样,因此rand
会生成相对随机的数字供使用。下面看一个设计实例。
猜数字游戏实现
猜数字游戏(1~100之间)可以作为随机数生成和使用的练习,下面详细叙述一下实现过程。
思路
- 生成1~100之间的随机数;
- 猜测这个数字,PC根据键盘输入判断所输入的数字与随机数的大小关系并返回;
有了思路,就可以开始一步一步写代码了。
随机数生成
srand((unsigned int)time(NULL));
int r = rand()%100 +1 ;//生成1
猜数字
int guess = 0;
scanf("%d",&guess);
if(guess > r)
{
printf("太大了\n");
}
else if(guess < r)
{
printf("太小了\n");
}
else
{
printf("猜对了!\n");
}
由于猜数字肯定不是仅有1次,而是不断的猜。因此猜测的过程需要循环。那么把代码改进一下:
while(1)
{
int guess = 0;
scanf("%d",&guess);
if(guess > r)
{
printf("太大了\n");
}
else if(guess < r)
{
printf("太小了\n");
}
else
{
printf("猜对了!\n");
break;//猜对了就要跳出循环
}
}
最终实现
玩游戏就需要加一点说明和提示。
void menu()
{
printf("***********************\n");
printf("******1. 进行游戏 *****\n");
printf("******0. 退 出 *****\n");
printf("***********************\n");
}
void game()
{
int r = rand()%100 + 1;
int guess = 0;
int count = 5;
while (count)
{
printf("你还有%d次机会, 请输入数字:>",count);
scanf("%d", &guess);
if (guess > r)
{
printf("太大了\n");
count--;
}
else if (guess < r)
{
printf("太小了\n");
count--;
}
else
{
printf("猜对了\n");
break;
}
}
if (count == 0)
{
printf("机会用尽,数字是%d\n", r);
}
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
//生成随机数
do{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
case 0:
break;
default:
printf("输入错误,请重新输入:>\n");
}
} while (input);
return 0;
}
上面的代码加入了次数限制,这样玩起来更有意思。
数组的创建和探索
这块本节课没有太深入,仅仅记录几个需要注意的点。
- 一个数组除过数组名就是数组类型;
- 二维数组的元素是一维数组,三维数组的元素是二维数组,依次套娃;
- 数组在内存中是连续存储的;
- 数组可以通过下标访问;
- 数组下标从0开始;
- 二维数组必须指定列数(作为元素的一维数组中的元素个数);
- sizeof(数组名)返回的是整个数组的大小(以字节计);
- 二维数组的不完全初始化可以使用
{}
标记每个元素; - C99之前,数组大小必须是常量、常量表达式;
- C99开始支持变长数组,这里不是说变长数组的大小可以随意变化,而是说数组的大小可以用变量了;
- 变长数组不能初始化;