当前位置: 首页 > news >正文

红黑树底层封装map、set C++

目录

一、框架思考

三个问题

问题1的解决

问题2的解决:

问题3的解决:

二、泛型编程

1、仿函数的泛型编程

2、迭代器的泛型编程

3、typename:

4、++/--重载

三、原码

红黑树

map

set


一、框架思考

map和set都是使用红黑树底层,要怎么实现同一个底层,但是实现不同的功能呢?

三个问题


1、map是pair模型,而set是key模型

2、map和set的迭代器用法是一样的,如何实现?

3、插入时,set和map插入的类型不同,如何实现?

我们是一个简单的实现,而不是全部,所以抓重点,化繁为简
只关注和当前我么要实现功能有关系的部分,其他的统统不关注

问题1的解决


RBTree的节点传的是一个模板

template<class T>
struct BRTreeNode
{BRTreeNode<T>* _parent;BRTreeNode<T>* _right;BRTreeNode<T>* _left;T _data;Colour _col;BRTreeNode(const T& data):_parent(nullptr), _right(nullptr), _left(nullptr), _data(data), _col(RED){}};

map传<K,pair<K,V>>
set传<K,K>

我set要用的是key模型的BRTree,所以传的是<K,K>
我map要的是key-value模型的BRTree,所以传的是<K,pair<K,V>>
对应的BRTree传对应的模板到Node,实现不同类型的Node节点

问题2的解决:

map和set底层都是红黑树,其行为都是一致的,问题在于节点数据类型的不同,所以,红黑树的底层迭代器实现都是一样的,设置为模板,因此和问题1的解决思路是一致的。

问题3的解决:


set和map的比较不一样
set的比较是直接key,而map的比较是用kv.first
不确定是map还是set,不能写死,怎么办?
可以写一个内部类的仿函数
这个仿函数,对于set返回的是其key值
对于map返回的是其kv.first值
仿函数是一个强大的功能,你想怎么实现就怎么实现

模板写成一样的,功能是一样的,但是不同的对象类具体实现不同的功能

具体解决请看以下的泛型编程过程

二、泛型编程

1、仿函数的泛型编程


set和map的key值不一样
如何使用同一份红黑树实现不同的比较逻辑?
当对红黑树实例化时,多传一个参数,即仿函数
在红黑树底层使用一个模板仿函数
在各自的map和set写好各自的类,用于模板仿函数的实例化
这样,虽然在底层,仿函数的行为都是一致的
但是,因为模板参数不同,其返回值也就不同

set的仿函数:

	struct  SetKeyOfT{const K& operator()(const K& key){return key;}};

map的仿函数:

		struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};

红黑树部分的仿函数

		KeyOfT kot;kot(data)


2、迭代器的泛型编程

set和map有各自的数据类型
但是器迭代器的形式是一样的
如何做到?
迭代器实现,实在红黑树部分实现的
将之设置为模板
传set,就是se对应的迭代器
传map,就是map对应的迭代器

set的迭代器:

	typedef typename BRTree<const K,  K, SetKeyOfT>::Iterator iterator;iterator begin(){return _t.Begin();}iterator end(){return _t.End();}

map的迭代器:

	typedef typename BRTree<K, pair< K, V>, MapKeyOfT>::Iterator iterator;iterator begin(){return _t.Begin();}iterator end(){return  _t.End();}

红黑树的迭代器:

//迭代器
//referrence :引用
template<class T, class Ptr, class Ref>//迭代器模板:数据类型、指针类型、解引用
struct __RBTreeiterator
{typedef BRTreeNode<T> Node;typedef __RBTreeiterator<T, Ptr, Ref> Self;//这个迭代器的对象Node* _node;__RBTreeiterator( Node* node):_node(node){}//解引用Ref operator*(){return _node->_data;}//->Ptr operator->(){return &_node->_data;}//比较bool operator!=(const Self& s)//比较的是两个迭代器对象,参数是另外一个迭代器对象{return  _node != s._node;}//++Self& operator++(){if (_node->_right)//如果右孩子不为空,找到右子树最小孩子{Node* leftMin = _node->_right;while (leftMin->_left){leftMin = leftMin->_left;}_node = leftMin;}else//右孩子为空{Node* cur = _node;Node* parent = _node->_parent;while (parent && cur == parent->_right)//当孩子作为父亲的左,这个父亲就是要访问的节点{cur = parent;parent = parent->_parent;}_node = parent;}return *this;//this为这个对象指针}};

一般的迭代器的功能:
解引用*
指针访问->
比较相等
++
--

3、typename:

在没有实例化的对象,访问其内嵌类型 
会出现分不清楚的问题:
因为静态成员、内部类、内部成员的访问都可以使用类域的方式去访问
没有实例化,就不知道访问哪一个 

在没有实例化模板的类对象去取器内嵌类型时,加一个typename
意义就是告诉编译器,等到实例化的时候再去找对应的内嵌类型

4、++/--重载

红黑树采用的是中序遍历
中序遍历,++返回的是当前节点中序遍历的下一个节点
顺序是:左,根、右
因此,需要分情况
如果当前节点有右孩子,那就是右孩子的最左节点

如果当前节点没有右孩子,那么说明自己这棵子树已经访问完毕
需要访问该子树的父亲,因为该子树是作为父亲的左孩子
按照中序遍历的思想,左子树访问完毕,接下来要访问的就是根

红黑树

#pragma once
#pragma once
#include<vector>
#include<iostream>
using namespace std;enum Colour
{BLACK,RED
};//node实例化,只给一个T
template<class T>
struct BRTreeNode
{BRTreeNode<T>* _parent;BRTreeNode<T>* _right;BRTreeNode<T>* _left;T _data;Colour _col;BRTreeNode(const T& data):_parent(nullptr), _right(nullptr), _left(nullptr), _data(data), _col(RED){}};//迭代器
//referrence :引用
template<class T, class Ptr, class Ref>//迭代器模板:数据类型、指针类型、解引用
struct __RBTreeiterator
{typedef BRTreeNode<T> Node;typedef __RBTreeiterator<T, Ptr, Ref> Self;//这个迭代器的对象Node* _node;__RBTreeiterator( Node* node):_node(node){}//解引用Ref operator*(){return _node->_data;}//->Ptr operator->(){return &_node->_data;}//比较bool operator!=(const Self& s)//比较的是两个迭代器对象,参数是另外一个迭代器对象{return  _node != s._node;}//++Self& operator++(){if (_node->_right)//如果右孩子不为空,找到右子树最小孩子{Node* leftMin = _node->_right;while (leftMin->_left){leftMin = leftMin->_left;}_node = leftMin;}else//右孩子为空{Node* cur = _node;Node* parent = _node->_parent;while (parent && cur == parent->_right)//当孩子作为父亲的左,这个父亲就是要访问的节点{cur = parent;parent = parent->_parent;}_node = parent;}return *this;//this为这个对象指针}};template<class K, class T, class KeyOfT>
class BRTree
{typedef BRTreeNode<T> Node;
public:typedef  __RBTreeiterator<T, T*, T&>Iterator;//提供迭代器接口Iterator Begin(){Node* leftMin = _root;while (leftMin && leftMin->_left)//如果为空,直接返回{leftMin = leftMin->_left;}//返回一个迭代器//return leftMin;单参数的构造函数支持隐式类型转换return Iterator(leftMin);}Iterator End(){//遍历,要访问到最大的值为止//一般end位置为空return Iterator(nullptr);}bool Insert(const T& data){if (_root == nullptr){_root = new Node(data);_root->_col = BLACK;return true;}KeyOfT kot;Node* cur = _root;Node* parent = nullptr;while (cur){//现在,不知道是k还是k-v模型//set访问的直接是key,而map访问的.first//所以,对应不同的返回值,仿函数解决if (kot(data) < kot(cur->_data)){parent = cur;cur = cur->_left;}else if (kot(data) > kot(cur->_data)){parent = cur;cur = cur->_right;}else//找到相等key{return false;}}cur = new Node(data);cur->_col = RED;if (kot(data) < kot(parent->_data))//插入左{parent->_left = cur;}else //插入右{parent->_right = cur;}cur->_parent = parent;//插入之后,要进行颜色调整while (parent && parent->_col == RED)//如果为空/黑色节点,直接结束{//Node* grandfather = parent->_parent;if (parent == grandfather->_left)//p为左,u为右{Node* uncle = grandfather->_right;//如果叔叔存在,且为红色if (uncle && uncle->_col == RED){//修改颜色parent->_col = uncle->_col = BLACK;grandfather->_col = RED;//向上更新cur = grandfather;parent = cur->_parent;}else//叔叔不存在/叔叔存在且为黑色{if (cur == parent->_left){//		   g//	   p      u//  c//RotateR(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//		   g//	   p      u//      c//RotateL(parent);//		   g//	   c      u//  p//RotateR(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}else//p为右,u为左{Node* uncle = grandfather->_left;//如果叔叔存在,且为红色if (uncle && uncle->_col == RED){//修改颜色parent->_col = uncle->_col = BLACK;grandfather->_col = RED;//向上更新cur = grandfather;parent = cur->_parent;}else//叔叔不存在/叔叔存在且为黑色{if (cur == parent->_right){//		   g//	   u      p//					c//RotateL(grandfather);parent->_col = BLACK;grandfather->_col = RED;}else{//		   g//	   u      p//          c//RotateR(parent);//		   g//	   u      c//  				p//RotateL(grandfather);cur->_col = BLACK;grandfather->_col = RED;}break;}}}_root->_col = BLACK;return true;}//右旋void RotateR(Node* parent){Node* subL = parent->_left;Node* subLR = subL->_right;parent->_left = subLR;if (subLR)//subLR可能为空{subLR->_parent = parent;}subL->_right = parent;Node* ppNode = parent->_parent;parent->_parent = subL;//注意修改顺序if (parent == _root){_root = subL;_root->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = subL;}else{ppNode->_right = subL;}subL->_parent = ppNode;}}//左旋void RotateL(Node* parent){Node* subR = parent->_right;Node* subRL = subR->_left;parent->_right = subRL;if (subRL){subRL->_parent = parent;}subR->_left = parent;Node* ppNode = parent->_parent;parent->_parent = subR;if (parent == _root){_root = subR;_root->_parent = nullptr;}else{if (ppNode->_left == parent){ppNode->_left = subR;}else{ppNode->_right = subR;}subR->_parent = ppNode;}}//检查平衡bool isBalance(){if (_root->_col == RED){return false;}//找到任意一条路黑色节点个数Node* cur = _root;int refNum = 0;while (cur){if (cur->_col == BLACK){refNum++;}cur = cur->_left;}return Check(_root, 0, refNum);return 1;}void Inoder(){_Inoder(_root);cout << endl;}private:bool Check(Node* root, int blackNum, const int refNum){//到路径结束位置检查黑色节点if (root == nullptr){if (blackNum != refNum){cout << "黑色节点不相等" << endl;return false;}// << blackNum << endl;return true;}//检查红色节点if (root->_col == RED && root->_parent->_col == RED){cout << root->_kv.first << "连续红节点" << endl;return false;}if (root->_col == BLACK){blackNum++;}return Check(root->_left, blackNum, refNum)&& Check(root->_right, blackNum, refNum);}void _Inoder(const Node* root){if (root == nullptr){return;}_Inoder(root->_left);cout << root->_kv.first << ":" << _root->_kv.second << endl;_Inoder(root->_right);}private:Node* _root = nullptr;};

map

#pragma once
#include"BRTree.h"//对map的封装namespace myNameSpace
{template<class K, class V>class map{struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};public://插入bool insert(const  pair <K, V>& kv){return _t.Insert(kv);}//封装红黑树的迭代器typedef typename BRTree<K, pair< K, V>, MapKeyOfT>::Iterator iterator;iterator begin(){return _t.Begin();}iterator end(){return  _t.End();}BRTree< K, pair <K, V>, MapKeyOfT> _t;};void test_map(){/*map<int, int> m;m.insert({1,1});m.insert({2,2});m.insert({3,1});m.insert({7,1});map<int,int>::iterator it = m.begin();while (it != m.end()){cout << it->first << ":" << it->second << endl;++it;}cout << endl;*/map<string, int> m1;m1.insert({ "hello",1});m1.insert({ "world",2});m1.insert({ "find",1});m1.insert({ "peace",1});map<string, int>::iterator it1 = m1.begin();while (it1 != m1.end()){cout << it1->first << ":" << it1->second << endl;++it1;}cout << endl;}}

set

#pragma once
#include"BRTree.h"namespace myNameSpace {template<class K>class set {struct  SetKeyOfT{const K& operator()(const K& key){return key;}};public:bool insert(const K& key){return _t.Insert(key);}//对于红黑树的迭代器,需要实例化红黑树的迭代器//所以需要在红黑树的基础上封装迭代器typedef typename BRTree<const K,  K, SetKeyOfT>::Iterator iterator;iterator begin(){return _t.Begin();}iterator end(){return _t.End();}private:BRTree<const K,K, SetKeyOfT> _t;};void test_set(){set<int> s;s.insert(1);s.insert(2);s.insert(4);s.insert(7);s.insert(8);s.insert(9);set<int>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;}}

相关文章:

红黑树底层封装map、set C++

目录 一、框架思考 三个问题 问题1的解决 问题2的解决&#xff1a; 问题3的解决&#xff1a; 二、泛型编程 1、仿函数的泛型编程 2、迭代器的泛型编程 3、typename&#xff1a; 4、/--重载 三、原码 红黑树 map set 一、框架思考 map和set都是使用红黑树底层&…...

压力给到 Google,OpenAI 发布 GPT-4o 来了

北京时间5月14日凌晨1点&#xff0c;OpenAI 开启了今年的第一次直播&#xff0c;根据官方消息&#xff0c;这次旨在演示 ChatGPT 和 GPT-4 的升级内容。在早些时候 Sam Altman 在 X 上已经明确&#xff0c;「我们一直在努力开发一些我们认为人们会喜欢的新东西&#xff0c;对我…...

【SpringSecurity源码】过滤器链加载流程

theme: smartblue highlight: a11y-dark 一、前言及准备 1.1 SpringSecurity过滤器链简单介绍 在Spring Security中&#xff0c;过滤器链&#xff08;Filter Chain&#xff09;是由多个过滤器&#xff08;Filter&#xff09;组成的&#xff0c;这些过滤器按照一定的顺序对进…...

第9章.Keil5-MDK软件简介

目录 0. 《STM32单片机自学教程》专栏 9.1 主界面 9.2 文本格式编辑 9.3 代码提示&语法检测&代码模版 9.4 其他小技巧 9.4.1 TAB 键的妙用 9.4.2 快速定位函数/变量被定义的地方 9.4.3 快速注释与快速消注释 9.4.4 快速打开头文件 9.4.5 查找替换…...

mysql中utf8字符集中文字节长度统计如何统计到2个字节一个汉字

在 MySQL 的 utf8 字符集中&#xff08;也被称为 utf8mb3&#xff09;&#xff0c;中文字符实际上并不是用2个字节来表示的&#xff0c;而是使用3个字节。这是 UTF-8 编码的一个特性&#xff0c;它使用1到4个字节来表示一个字符&#xff0c;具体取决于字符的 Unicode 码点。 对…...

如何实现Linux双网卡同时连接内网和外网的配置?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …...

ASCLL码表以及字符的相加减

ASCLL码表完整版及解释_acssll码-CSDN博客 #include <getopt.h> #include <stdio.h> #include <stdlib.h>#define MAX_PATH 256 char filename[MAX_PATH 5];int isdigit(int c) {if (c > 0 && c < 9)return 1;return 0; }int main(int argc…...

一键修复所有dll缺失,教大家解决丢失的dll文件

修复所有DLL&#xff08;动态链接库&#xff09;文件缺失的问题通常不可能通过单一的"一键修复"按钮来实现&#xff0c;因为DLL文件缺失可能由各种不同的原因导致&#xff0c;比如应用程序安装不正确、病毒感染、或系统文件损坏等。 使用内置的系统文件检查器&#x…...

wsl2安装rancher并导入和创建k8s集群

环境准备 安装wsl2点击此文]ubuntu20.04安装docker 点击此文,安装完成后docker镜像仓库改成阿里云镜像加速地址.如果不熟请点击此文 docker 安装rancher 启动wsl,根据官方文档以root身份执行 sudo docker run -d --restartunless-stopped -p 80:80 -p 443:443 --privileged …...

内网环境ubuntu设置静态ip、DNS、路由,不影响网络访问

内网环境通常是有线的&#xff0c;通过服务器的ip、mac、dns地址访问网络才生效的&#xff0c;如果ip地址变了&#xff0c;就不能访问网络了。 如果你的ip地址变了&#xff0c;或者要防止ip变更影响网络访问&#xff0c;就要设置 1、依次点击右上角的电源-设置&#xff0c;在打…...

学习前端第三十七天(静态属性静态方法、类检查、错误处理)

一、静态属性和静态方法 1、静态属性静态方法 在属性和方法前加上static&#xff0c;创建属于类自己的属性和方法 class Person {// 加static&#xff0c;属于类自己的static name "xc"; // 类的name属性static height 183; // 类的height属性static age 20;…...

全网最全的基于电机控制的38类simulink仿真全家桶----新手大礼包

整理了基于电机的38种simulink仿真全家桶&#xff0c;包含多种资料&#xff0c;类型齐全十分适合新手学习使用。包括但是不局限于以下&#xff1a; 1、基于多电平逆变器的无刷直流电机驱动simulink仿真 2、基于负载转矩的感应电机速度控制simulink仿真 3、基于滑膜观测器的永…...

Python使用asyncio包实现异步编程

1. 异步编程 异步编程是一种编程范式&#xff0c;用于处理程序中需要等待异步操作完成后才能继续执行的情况。异步编程允许程序在执行耗时的操作时不被阻塞&#xff0c;而是在等待操作完成时继续执行其他任务。这对于处理诸如文件 I/O、网络请求、定时器等需要等待的操作非常有…...

获取文件夹下的vue文件形成组件,require.context

前言&#xff1a;项目中现有一个文件里面包含所有需要用到的组件&#xff0c;如果一个个的去import&#xff0c;则会非常麻烦&#xff0c;现有require.context去实现&#xff0c; 1、require.context var request require.context(‘./module’, true, /.js$/) require.cont…...

2024软件测试必问的常见面试题1000问!

01、您所熟悉的测试用例设计方法都有哪些&#xff1f;请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。 答&#xff1a;有黑盒和白盒两种测试种类&#xff0c;黑盒有等价类划分法&#xff0c;边界分析法&#xff0c;因果图法和错误猜测法。白盒有逻辑覆盖法&…...

C++列表实现

文章目录 一、listView相关内容主要思想实例全部代码 二、QTreeView 一、listView 相关内容 QAbstractItemModel&#xff1a;一个抽象的类&#xff0c;为数据项模型提供抽象的接口&#xff0c;常见的的数据模型列如&#xff1a;QStringListModel,QStandardItemMode,QDirModel…...

论文合集整理推荐2024.5.15

‍2012年论文合集&#xff1a;论文入口 ‍2019年论文合集&#xff1a;论文入口 2022年论文合集&#xff1a;论文入口 2023年论文合集&#xff1a;论文入口 2024年论文合集&#xff1a;论文入口...

JavaScript的跳转传参方式

在JavaScript中&#xff0c;页面跳转并传递参数通常可以通过几种不同的方式来实现。下面是一些常见的方法&#xff1a; 1.URL参数&#xff08;Query String&#xff09; 这是最常见的方式&#xff0c;通过在URL的末尾添加参数来实现。例如&#xff1a; javascriptwindow.loc…...

非阻塞模式下的读写操作

实现文件IO的非阻塞模式的读写操作 fcntl函数 功能&#xff1a; #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); // arg表示可变参数&#xff0c;由cmd决定 fcntl()对打开的文件描述符fd执行下面描述的操作之一。操作由cmd决…...

Google Ads谷歌广告账户被封停怎么办?

跨境出海业务少不了需要做Google Ads推广业务&#xff1b;其中让投手们闻风丧胆的消息就是帐户被暂停。当 Google 检测到任何违反其政策且可能损害用户在线体验的行为时&#xff0c;就会发生这种情况。那么如何在做广告推广的同时&#xff0c;保证账号不被封禁呢&#xff1f;看…...

AI大模型探索之路-训练篇23:ChatGLM3微调实战-基于P-Tuning V2技术的实践指南

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…...

掌握核心概念:Java高级面试难题精解(一)

Java 高级面试问题及答案 问题1: 在Java中&#xff0c;什么是泛型擦除&#xff1f;为什么需要它&#xff1f; 答案&#xff1a; 泛型擦除是Java编译器的一个特性&#xff0c;它在运行时移除泛型类型信息&#xff0c;以确保类型安全。Java的泛型是在J2SE 1.5中引入的&#xff…...

Nagle算法

Nagle算法简介 Nagle算法主要是避免发送小的数据包&#xff0c;要求TCP连接上最多只能有一个未被确认的小分组&#xff0c;在该分组的确认到达之前不能发送其他的小分组。 在默认的情况下,Nagle算法是默认开启的&#xff0c;Nagle算法比较适用于发送方发送大批量的小数据&…...

MPLS小实验

实验图&#xff1a; 实验要求&#xff1a; 要求使用MPLS技术&#xff0c;将实验通&#xff0c;并在实验结束后使用命令&#xff1a;tracert -v -a 看是否基于标签进行转发。 如上&#xff1a;在每台路由器上都有两个环回&#xff0c;一个用于模拟用户网段&#xff0c;一个用于M…...

MongoDB聚合运算符:$week

MongoDB聚合运算符&#xff1a;$week 文章目录 MongoDB聚合运算符&#xff1a;$week语法使用举例 $week聚合运算符返回指定日期日期为一年中第几周的数字值为0到53之间。周从周日开始&#xff0c;第1周从一年的第一个周日开始。一年中第一个星期日之前的日期为第0周。这和 str…...

【Linux】如何定位客户端程序的问题

文章目录 1 客户端程序和服务端程序的差别2 问题类型2.1 崩溃(crash)2.2 CPU高2.3 内存高2.4 线程卡死 3 总结 1 客户端程序和服务端程序的差别 客户端程序是运行在终端上&#xff0c;通常都会与业务系统共存&#xff0c;而服务端程序通常会运行在单独的节点上&#xff0c;或者…...

AI学习指南数学工具篇-PCA基础知识

AI学习指南数学工具篇-PCA基础知识 1. PCA是什么&#xff1f; PCA&#xff0c;即主成分分析&#xff08;Principal Component Analysis&#xff09;&#xff0c;是一种常用的数据降维技术。它通过线性变换将原始数据投影到一个新的坐标系中&#xff0c;旨在找到数据中的“主成…...

《系统架构设计师教程(第2版)》第4章-信息安全技术基础知识-02-信息加密技术

文章目录 1. 信息加密技术1.1 数据加密1.2 对称密钥加密算法1&#xff09;数据加密标准&#xff08;DES)2&#xff09;三重DES&#xff08;Triple-DES&#xff09;3&#xff09;国际数据加密算法&#xff08;IDEA&#xff09;4&#xff09;高级加密标准&#xff08;AES&#xf…...

Leetcode 404:左叶子之和

给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 思路&#xff1a;遍历树&#xff0c;寻找左叶子节点&#xff1b; 如果判断是左叶子节点&#xff0c;就更新sum。 public static int sumOfLeftLeaves(TreeNode root){int sum0;sumcompute(root,sum);return sum;}/…...

Keil问题解决:结构体数组初始化,初始化后的值不是目标值

省流&#xff1a;使用的编译器为compiler version 6&#xff0c;切换为compiler version 5 如果缺少编译器&#xff0c;请参考&#xff1a;Keil手动安装编译器V5版本 结构体定义&#xff1a; typedef struct _TASK_COMPONENTS {uint8_t Run; // 程序运行标…...