本文中的代码都在Visual Studio(版本为2022)软件中运行,在使用scanf函数记得在第一行写下面的代码:
#define _CRT_SECURE_NO_WARNINGS
在编写代码之前先了解3个函数:rand()函数、srand()函数、time()函数和相关概念。
rand()函数的语法规则:
int rand (void);
void表示函数不接受任何参数
int表示函数返回值的类型为整形
在c语言中,rand()函数的作用是用于生成伪随机数,它定义在<stdlib.h>头文件中,使用时,应先引入这个头文件。
伪随机数的概念:伪随机数是在计算机程序中生成的一系列看似随机但实际上是通过确定的算法计算出来的数值。
伪随机数的范围:0到RAND_MAX (包括0和RAND_MAX )
RAND_MAX在不同的编译器上的值是不同的,值的范围为:32767到2147483647 (包括32767和2147483647) 在查找各类型数据时,可以通过下载Everything软件,在软件中,搜索所求类型所在的头文件,就能找到类型的范围取值。
rand()函数生成伪随机数的原理:以rand()函数的种子值为基础值,通过伪随机数生成器和线性同余生成器这两个算法,生成一系列的伪随机数。(当种子值相同时,生成的一系列的伪随机数也相等,只有种子值不相等时,生成的一系列的伪随机数才不相等。)
c语言中rand()函数的种子值是通过srand()函数生成的。在不使用srand()函数设置种子值时,种子值通常是1。
使用rand()函数生成3个伪随机数,代码如下:
#include <stdio.h> int main() { printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand()); return 0; }
运行结果为:
41 18467 6334
再次运行时,结果为:
41 18467 6334
两次运行的结果一样是因为两次运行时的种子值相等,故生成的一系列伪随机数相等。
srand()函数的语法规则:
void srand (unsigned int seed);
参数类型为无符号整型(unsigned int) 该类型只有零和正数
void表示函数无返回值
srand()函数定义在<stdlib.h>中,使用时,应先引入这个头文件。
通过使用srand()函数设置种子值,可以让种子值发生变化,因此,使用rand()函数得到的一系列伪随机数也是不一样的。
注意:一定要先使用srand()函数设置种子值,再使用rand()函数生成一系列的伪随机数。
使用rand()函数和srand()函数,生成3个伪随机数,代码如下:(用srand()函数将种子值设置为1)
#include <stdio.h> int main() { srand(1); printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand()); return 0; }
运行结果:
41 18467 6334
用srand()函数将种子值设置为2
#include <stdio.h> #include <stdlib.h> int main() { srand(2); printf("%d\n", rand()); printf("%d\n", rand()); printf("%d\n", rand()); return 0; }
运行结果:
45 29216 24198
time()函数的语法规则:
time_t time (time_t* time);
参数:time是一个指向time_t类型的指针。(这里不理解,不影响编写代码)
函数的返回值是从1970年1月1日0时0分0秒到现在程序运行时间之间的差值,单位是秒。
time_t类型,本质上32为或64为的整型类型。
time()定义在<time.h>头文件中,使用时,应先引入这个头文件。
当参数time为NULL,就会返回从1970年1月1日0时0分0秒到现在程序运行时间之间的差值。
使用time()函数,获得1970年1月1日0时0分0秒到现在程序运行时间之间的差值,代码如下:
#include <stdio.h> #include <time.h> int main() { printf("%d", time(NULL)); return 0; }
运行结果为:
1720610137
学完上述三个函数之后,我们可以使用下面的这种方式生成任意的随机数(有范围)
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand((unsigned int)time(NULL)); int random_number = rand(); printf("%d%, random_number); return 0; }
运行的结果为一个数字,该数字的范围为0到RAND_MAX(包括0和RAND_MAX),在Visual Studio(2022)中,RAND_MAX的值为32767。
注意:time()函数返回值的类型为整形,而srand()函数的参数的类型为无符号整型(unsigned int),故将time()函数返回值作为srand()函数的参数时,需要将time()函数返回值转换为无符号整型(unsigned int)
代码分析:
当我们要生成任意一个随机数时(随机数有范围),我们应该将time(NULL)函数的返回值作为srand()函数的参数,最后使用rand()函数就可以生成不同的伪随机数。
(解释:time(NULL)函数的返回值随着时间的变化而变化,将其返回值作为srand()函数的参数,可以得到不同的种子值,并且种子值是自动变化,不用手动改变。rand()函数是以种子值为基准值,然后通过算法获得伪随机数的,故只要我们能够改变种子值,就可以获得不同的伪随机数。对同一个种子值来说,使用rand()函数获得的伪随机数是相同的。)
若想让产生的随机值有范围的话,只需修改上述的第8行代码即可。例如若想生成1到99之间的数字(包括1和99),可以将其求改为:
int random_number = rand() % 100 + 1;
原理:在无符号整型(没有负数)中,假设整数a对整数b取模,则结果为0到b-1(包括0和b-1)。所以rand() % 100 的范围为0到99(包括0和99),然后加1,范围为1到100(包括1和100)
如果要生成a到b(包括a和b)的随机数,方法如下:
a + rand()%(b-a+1)
猜数字游戏,数字范围为1到100(包括1和100) (没有次数限制)
#include <stdio.h> #include <stdlib.h> #include <time.h> void menu() { printf("************************\n"); printf("****** 1.游戏开始 ******\n"); printf("****** 0.游戏结束 ******\n"); printf("************************\n"); } void guessnumber_game() { int random_number = rand() % 100 + 1; //获得1到100(包括1和100)的任意一个随机数 int guess_number = 0; printf("请输入你所猜的数字:"); while (1) //使用while循环直到猜对才停止循环 { scanf("%d", &guess_number); if (guess_number > random_number) { printf("猜大了,请重新输入猜的数字:"); } else if (guess_number < random_number) { printf("猜小了,请重新输入猜的数字:"); } else { printf("恭喜你,猜对了\n\n"); break; } } } int main() { int input_number = 0; srand((unsigned int)time(NULL)); //设置种子值 while (1) //使用while循环,使得游戏上一句游戏结束时,可以进行下一句游戏。 { menu(); //调用menu()函数,执行里面的代码 printf("请输入你要选择的数字:"); scanf("%d", &input_number); switch (input_number) { case 1: guessnumber_game(); //调用guessnumber_game()函数,执行里面的代码 break; case 0: printf("退出游戏\n\n"); break; default: printf("请输入正确的选择数字"); } if (input_number == 0) //当input_number为0时,才能结束while循环,退出游戏 { break; } } return 0; }
有次数限制:
#include <stdio.h> #include <stdlib.h> #include <time.h> void menu() { printf("************************\n"); printf("****** 1.游戏开始 ******\n"); printf("****** 0.游戏结束 ******\n"); printf("************************\n"); } void guessnumber_game() { int random_number = rand() % 100 + 1; //获得1到100(包括1和100)的任意一个随机数 int guess_number = 0; int count = 5; //设置5次猜数字的机会 while (1) //使用while循环直到猜对才停止循环 { printf("你还有%d次机会\n", count); printf("请输入你所猜的数字:"); scanf("%d", &guess_number); if (guess_number > random_number) { printf("猜大了\n"); } else if (guess_number < random_number) { printf("猜小了\n"); } else { printf("恭喜你,猜对了\n\n"); break; } count--; //猜错一次,count数值减一 if (count == 0) { printf("你失败了,正确的结果为:%d\n\n", random_number); break; } } } int main() { int input_number = 0; srand((unsigned int)time(NULL)); //设置种子值 while (1) //使用while循环,使得游戏上一句游戏结束时,可以进行下一句游戏。 { menu(); //调用menu()函数,执行里面的代码 printf("请输入你要选择的数字:"); scanf("%d", &input_number); switch (input_number) { case 1: guessnumber_game(); //调用guessnumber_game()函数,执行里面的代码 break; case 0: printf("退出游戏\n\n"); break; default: printf("请输入正确的选择数字"); } if (input_number == 0) //当input_number为0时,才能结束while循环,退出游戏 { break; } } return 0; }