分析rand()和srand()函数的功能

rand()和srand()函数原型:

int rand(void) 返回一个范围在 0 到 RAND_MAX 之间的伪随机数。

void srand(unsigned int seed)用来给rand() 设置随机数发生器,随机数发生器输出不同的数值,rand() 就会生成不同的随机数

1)、在“D:\Keil_v5\ARM\ARMCC\include\stdlib.h”中,有下面的定义:

#ifdef __USE_ANSI_EXAMPLE_RAND

#define srand _ANSI_srand

#define rand _ANSI_rand

#define RAND_MAX 0x7fff

#else

#define RAND_MAX 0x7fffffff  /*MDK-ARM默认使用RAND_MAX0x7fffffff*/

#endif

MDK-ARM默认使用RAND_MAX0x7fffffff

2)、在“D:\Keil_v5\ARM\ARMCC\include\time.h”中,有下面的定义:

extern _ARMABI time_t time(time_t * /*timer*/);

但是time没有具体的函数,因此“srand((unsigned int)time(NULL))”就不能用了。

srand()函数用生成随机数种子。当我们使用相同的种子时,将生成相同的随机数序列。为了能rand()函数生成不同的随机数,可以使用“TIM1的计数器值”作为作为种子值因为“TIM1的计数器值”是不断变化的,这样每次运行rand()函数,就可以生成不同的随机数序列。

3)、测试rand()和srand()函数

void TIM1_Interrupt_Initializtion(u16 arr,u16 psc);//函数声明

//定时器1中断初始化

//APB2时钟为72MHz

//arr:自动重装值。

//psc:时钟预分频数

//TIM_CKD_DIV1:定时器时钟 = 输入频率

//TIM_CKD_DIV2:定时器时钟 = 输入频率/2

//TIM_CKD_DIV4:定时器时钟 = 输入频率/4

//TIM1溢出时间: arr*psc/72000000/TIM_CKD_DIVx

//TIM1_Interrupt_Initializtion(1000,72);

//当arr=1000,psc=72时,则为1ms,误差为1us;

void TIM1_Interrupt_Initializtion(u16 arr,u16 psc)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

//使能定时器TIM1的APB2外设时钟

//定时器TIM1初始化

TIM_TimeBaseStructure.TIM_Period = arr-1;

//设置在下一个更新事件装入活动的自动重装载寄存器周期的值

TIM_TimeBaseStructure.TIM_Prescaler =psc-1;

//设置用来作为TIMx时钟频率除数的预分频值

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

//设置时钟分割:TDTS = Tck_tim

//计算公式:arr*psc/72000000/1,当arr=1000,psc=72时,则为1ms,误差为1us;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

//TIM向上计数模式

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

//根据指定的参数初始化TIMx的时间基数单位

  TIM_SetCounter(TIM1,0);                      //设置TIM1的计数器值为0;

  TIM_ClearFlag(TIM1, TIM_FLAG_Update);        //清除TIM1溢出的待处理标志位

TIM_ClearITPendingBit(TIM1, TIM_IT_Update ); //清除TIM1中断的待处理位

// TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE ); //允许TIM1溢出产生中断

/*中断优先级NVIC设置

NVIC_PriorityGroup_4设置NVIC中断分组4:表示抢占优先级为4位,取值为0~15,没有响应优先级,取值为0

NVIC_PriorityGroup_3设置NVIC中断分组3:表示抢占优先级为3位,取值为0~7,响应优先级只有1位,取值为0~1

NVIC_PriorityGroup_2设置NVIC中断分组3:表示抢占优先级为2位,取值为0~3,响应优先级只有2位,取值为0~3

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4

NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  //TIM1中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11;  //设置抢占优先级为11

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //设置响应优先级为0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ通道被使能

NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化NVIC嵌套向量中断控制寄存器

*/

TIM_Cmd(TIM1, ENABLE);//使能TIM1外设

}

#include "stdlib.h"

//rand()和srand()需要包含stdlib.h头文件

void Test_rand_And_srand(void)

{

unsigned int rand_Value;//声明无符号32位变量rand_Value

unsigned int ms;//声明无符号32位变量ms

rand_Value=rand(); //返回一个范围在0到RAND_MAX之间的伪随机数

ms=rand_Value%1000+1;//ms为1到1000之间的数

printf("ms=%u\r\n",ms);

}

int main(void)

{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4

USART1_Serial_Interface_Enable(115200);

printf("\r\nCPU reset\r\n");

    TIM1_Interrupt_Initializtion(1000,72);

//当arr=1000,psc=72时,则为1ms,误差为1us;

srand( TIM_GetCounter(TIM1) );//使用“TIM1的计数器值”作为作为种子值

  while(1)

  {

Test_rand_And_srand();

  }

}

仿真结果:

3)、在MDK-ARM中,不用srand()设置随机数发生器,也可以使用rand()得到不同的随机数。

#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "USART1.h"
//注意:"USART1.h"要放在 "stdio.h" 包含文件之后,如果这个位置颠倒了,业不能打印浮点数。#include "stdlib.h"
//rand()需要包含stdlib.h头文件void Test_Rand(void)
{unsigned int rand_Value;//声明无符号32位变量rand_Valueunsigned int ms;//声明无符号32位变量msrand_Value=rand(); //返回一个范围在0到RAND_MAX之间的伪随机数printf("rand_Value=%u\r\n",rand_Value);ms=rand_Value%1000+1;//ms为1到1000之间的数printf("ms=%u\r\n",ms);
}int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4USART1_Serial_Interface_Enable(115200);printf("\r\nCPU reset\r\n");while(1){Test_Rand();}
}

 仿真结果如下:

4)、如果在调用rand()前,每次都使用srand()设置一个常数作为种子,就会得到相同的随机数。

#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "USART1.h"
//注意:"USART1.h"要放在 "stdio.h" 包含文件之后,如果这个位置颠倒了,业不能打印浮点数。#include "stdlib.h"
//rand()需要包含stdlib.h头文件void Test_Rand(void)
{unsigned int rand_Value;//声明无符号32位变量rand_Valueunsigned int ms;//声明无符号32位变量mssrand(1);rand_Value=rand(); //返回一个范围在0到RAND_MAX之间的伪随机数printf("rand_Value=%u\r\n",rand_Value);ms=rand_Value%1000+1;//ms为1到1000之间的数printf("ms=%u\r\n",ms);
}int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4USART1_Serial_Interface_Enable(115200);printf("\r\nCPU reset\r\n");while(1){Test_Rand();}
}

仿真结果:

5)、 如果在调用rand()前,只用一次srand()设置一个常数作为种子,可以得到不同的随机数。

#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "USART1.h"
//注意:"USART1.h"要放在 "stdio.h" 包含文件之后,如果这个位置颠倒了,业不能打印浮点数。#include "stdlib.h"
//rand()需要包含stdlib.h头文件void Test_Rand(void)
{unsigned int rand_Value;//声明无符号32位变量rand_Valueunsigned int ms;//声明无符号32位变量msrand_Value=rand(); //返回一个范围在0到RAND_MAX之间的伪随机数printf("rand_Value=%u\r\n",rand_Value);ms=rand_Value%1000+1;//ms为1到1000之间的数printf("ms=%u\r\n",ms);
}int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4USART1_Serial_Interface_Enable(115200);printf("\r\nCPU reset\r\n");srand(1);while(1){Test_Rand();}
}

仿真结果:

为什么在keil中,会出现这种结果?

在Keil环境中,如果不使用srand()函数,直接调用rand()函数也可以生成随机数。调用rand()不但可以生成一个新的随机数,而且也会更新“种子值”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

debuginfo详解

debuginfo 是 Linux 系统中存储调试符号和源代码信息的特殊软件包,用于分析内核或用户态程序的崩溃转储文件(如 vmcore、coredump)。它在调试复杂问题(如内核崩溃、程序段错误)时至关重要。以下是其核心作用、安装方法…

Python 爬取微店商品列表接口(item_search)的实战指南

在电商数据分析、市场调研或竞品分析中,获取商品列表信息是常见的需求。微店作为知名的电商平台,提供了丰富的商品资源和相应的 API 接口。本文将详细介绍如何使用 Python 爬虫技术,通过微店的 item_search 接口根据关键词搜索商品列表&#…

【bazel】bazel简介及简单使用

文章目录 1. What is bazel?2. bazel的核心原理2.1 bazel的构建模型2.2 bazel的核心概念2.3 bazel的关键特性 3. bazel的使用3.1 划分项目结构3.2 编写BUILD文件3.3 bazel常用命令3.4 bazel依赖管理 参考内容 1. What is bazel? bazel是一个开源的构建工具,它基于…

【Mytais系列】Myatis的设计模式

目录 设计模式 1. 工厂模式(Factory Pattern) 2. 建造者模式(Builder Pattern) 3. 动态代理模式(Dynamic Proxy Pattern) 4. 模板方法模式(Template Method Pattern) 5. 策略模…

【unity游戏开发入门到精通——UGUI】Mask组件实现UGUI遮罩

注意:考虑到UGUI的内容比较多,我将UGUI的内容分开,并全部整合放在【unity游戏开发——UGUI】专栏里,感兴趣的小伙伴可以前往逐一查看学习。 文章目录 前言如何实现UI遮罩1、Mask组件2、实例3、注意 专栏推荐完结 前言 Mask遮罩是…

Github2025-05-04php开源项目日报 Top10

根据Github Trendings的统计,今日(2025-05-04统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目10Shell项目1Vue项目1Java项目1ASP项目1SecLists - 安全测试人员的伴侣 创建周期:4375 天开发语言:PHP协议类型:MIT LicenseStar数量…

MyBatis 一对多与多对一映射详解教程

一、基础概念与场景 一对多(One-to-Many) • 定义:一个父对象包含多个子对象。 例如:一个商品(Goods)对应多个商品详情(GoodsDetail) • 实体类表现:父类中包含 List&l…

ChatGPT:重塑人工智能交互范式的破晓之作

2022年11月30日,总部位于旧金山的研究公司OpenAI正式发布了ChatGPT——一款以病毒式传播速度席卷全球的AI聊天机器人。它不仅能像人类一样生成内容、回答问题和解决问题,更在推出后的两个月内吸引了超过1亿月活跃用户,刷新了消费级技术应用的最快采用率纪录。这一里程碑事件…

在项目中如何对Map List等对象序列化及反序列化

我们知道,在自定义类中,若想完成序列化必须要实现Serializable接口。 那么在实现后如何进行序列化呢? 一.普通对象 序列化: 1.首先我们要定义一个 序列化所需要的工具类 ObjectMapper //定义序列化所需要的工具类 转化机器…

笔试专题(十五)

文章目录 排序子序列题解代码 消减整数题解代码 最长公共子序列(二)题解代码 排序子序列 题目链接 题解 1. 贪心 模拟 2. 1 2 3 2 2 应该是有两个排列子序列的,所以i n-1时ret 3. 把水平的位置和上升部分,水平位置和下降部分分为一个排列子序列 代…

Amazon Bedrock Converse API:开启对话式AI新体验

Amazon Bedrock Converse API:开启对话式AI新体验 前言 在当今人工智能飞速发展的时代,对话式AI已成为众多应用的核心组成部分。从智能客服到智能助手,对话式AI为用户带来了便捷且高效的交互体验。而Amazon Bedrock Converse API的出现&…

【Springboot知识】Springboot计划任务Schedule详解

文章目录 Spring Boot 定时任务从原理到实现详解一、核心原理分析1. 架构分层2. 核心组件3. 线程模型 二、基础实现步骤1. 添加依赖2. 主类配置3. 定时任务类 三、高级配置技巧1. 自定义线程池2. 动态配置参数3. 分布式锁集成(Redis示例) 四、异常处理机…

MySQL:联合查询

目录 一、笛卡尔积 ​二、内连接 三、外连接 (1)左外连接 (2)右外连接 (3)全外连接 四、自连接 五、子查询 (1)单行子查询 (2)多行子查询 &…

深入理解 Cortex-M3 的内核寄存器组

每个 MCU 开发工程师一定都了解寄存器这个东西,以 STM32 为例,其拥有非常多的外设模块,如串口、SPI、IIC 等等,如果要使用这些外设,使其按照我们的要求工作,就需要配置这些外设的寄存器,往这些寄…

网络安全自动化:找准边界才能筑牢安全防线

数字时代,企业每天要面对成千上万的网络攻击。面对庞大的服务器群、分散的团队和长期不重启的设备,很多企业开始思考:哪些安全操作适合交给机器自动处理?哪些必须由人工把关?今天我们就用大白话聊聊这件事。 一、这些事…

C++负载均衡远程调用学习之负载均衡算法与实现

目录 01 lars 系统架构回顾 02 lars-lbAgentV0.4-route_lb处理report业务流程 03 lars-lbAgentV0.4-负责均衡判断参数配置 04 lars-lbAgentV0.4-负载均衡idle节点的失败率判断 05 lars-lbAgentV0.4-负载均衡overload节点的成功率判断 06 lars-lbAgentV0.4-负载均衡上报提交…

领略算法真谛: 多源bfs

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的pa…

雷电模拟器-超好用的Windows安卓模拟器

一、雷电模拟器介绍 雷电模拟器是一款功能强大的软件,它能够在电脑上模拟出安卓手机系统,让你可以在电脑上运行各类手机应用及游戏。其采用虚拟安卓手机操作界面,为玩家带来了独特的体验。 (一)强大的兼容性 雷电模拟…

文章三《机器学习基础概念与框架实践》

文章3:机器学习基础概念与框架实践 ——从理论到代码,用Scikit-learn构建你的第一个分类模型 一、机器学习基础理论:三大核心类型 机器学习是人工智能的核心,通过数据让计算机自动学习规律并做出预测或决策。根据学习方式,可分为三类: 1. 监督学习(Supervised Learni…

脑机接口技术:开启人类与机器的全新交互时代

在科技飞速发展的今天,人类与机器的交互方式正经历着前所未有的变革。从最初的键盘鼠标,到触摸屏,再到语音控制,每一次交互方式的升级都极大地提升了用户体验和效率。如今,脑机接口(Brain-Computer Interfa…