1 伪随机数生成的核心机制
C语言标准库通过rand函数提供随机数生成能力,但其本质属于伪随机数(Pseudo-Random Number),而非物理意义上的真随机数。
1.1 rand 函数的工作特性
rand函数原型如下:
c
int rand(void);
该函数返回一个介于0到RAND_MAX之间的整数。在大多数编译器中,RAND_MAX的值为 32767。
关键特性:
rand并非真正随机,而是通过确定性算法计算得出;- 其输出依赖于一个称为 种子 (seed) 的初始值;
- 默认情况下,种子固定为
1,因此每次程序运行生成的随机数序列完全一致。
若不更改种子,多次运行程序将得到相同的"随机"结果,这在游戏或安全场景中是不可接受的。
2 种子初始化与 srand 函数
为使随机数序列发生变化,必须在调用rand之前初始化种子。
srand函数用于设置随机数生成器的种子,原型为:
c
void srand(unsigned int seed);
只要种子发生变化,rand生成的序列就会随之改变。
然而,这引出了一个递归问题:
若想生成随机数,需先有一个随机的种子;但获取随机种子本身又需要随机数。
为了解决该矛盾,通常采用时间作为种子来源。
3 基于时间戳的动态种子
3.1 time函数与时间戳
C语言提供time函数以获取当前时间,其原型为:
c
time_t time(time_t *timer);
- 返回值表示从 1970年1月1日 00:00:00 UTC 到当前时刻的秒数,称为时间戳;
- 参数通常为
NULL,仅返回时间差值; - 返回类型为
time_t,本质是整数类型。
3.2 完整初始化流程
结合time与srand,即可实现动态种子初始化:
c
#include <stdlib.h>
#include <time.h>
srand((unsigned int)time(NULL));
注意:srand只需在程序生命周期中调用一次,频繁调用(尤其在短时间内)会导致种子重复,进而产生相同随机数。
4 猜数字游戏的综合实现
猜数字游戏是分支与循环结构的典型综合应用,其核心逻辑包括:随机数生成、用户输入、条件判断与循环控制。
c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu() {
printf("===================================\n");
printf("=======Number Guessing Game========\n");
printf("===== 1 PLAY === 0 GAME OVER ======\n");
printf("===================================\n");
}
void play() {
int sysget = rand() % 100 + 1;
printf("%d\n", sysget);
printf("******************************************\n");
printf("Please enter an integer between 1 and 100:\n");
int get = 0;
int count = 0;
while (sysget != get) {
count++;
scanf("%d", &get);
if (get > sysget) {
printf("[COUNT:%d] WARNING: too high.\n", count);
}
else if (get < sysget) {
printf("[COUNT:%d] WARNING: too low.\n", count);
}
else {
printf("Congratulations to you.\n");
printf("\n");
break;
}
if (count == 5) {
printf("Maximum attempts reached, GAME FAILED.\n");
printf("\n");
break;
}
}
}
int main() {
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("Please Select:\n");
scanf("%d", &input);
switch (input) {
case 1:
play();
break;
case 0:
printf("Exit Game\n");
break;
default:
printf("Input error.\n");
break;
}
} while (input);
return 0;
}