单片机软件架构连载(3)-typedef

news2024/9/23 21:32:25

今天给大家讲typedef,这个关键字在实际产品开发中,也是海量应用。

技术涉及知识点比较多,有些并不常用,我们以贴近实际为原则,让大家把学习时间都花在重点上。

1.typedef的概念

typedef 是 C 语言中的一个关键字,可以为基本数据类型、结构体、联合体、枚举等创建一个新的类型名,有助工程师编写更清晰、更易于维护的代码。

2.typedef的几种用法

2.1用于基本数据类型

// 使用typedef关键字定义一个新类型名uint8_t,它代表无符号的8位字符(即0到255的整数)
typedef unsigned char uint8_t;

// 使用typedef关键字定义一个新类型名uint16_t,它代表无符号的16位短整型(即0到65535的整数)
typedef unsigned short uint16_t;

// 使用typedef关键字定义一个新类型名uint32_t,它代表无符号的32位整型(即0到4294967295的整数)
typedef unsigned int uint32_t;

// 声明一个类型为uint8_t的变量a,可以存储8位无符号整数
uint8_t a;

// 声明一个类型为uint16_t的变量b,可以存储16位无符号整数
uint16_t b;

// 声明一个类型为uint32_t的变量c,可以存储32位无符号整数
uint32_t c;

这段代码用typedef给unsigned char、unsigned short 和 unsigned int分别创建了uint8_t、uint16_t、uint32_t别名。

这里使用typedef给数据类型创建别名有什么作用或优势?

①.提高代码可读性

通过使用 uint8_t、uint16_t 和 uint32_t 这样的类型名,比直接使用基本数据类型 unsigned char、unsigned short 和 unsigned int 更易于理解。

②跨平台兼容性

不同的编译器或平台可能对基本数据类型的大小有不同的定义(例如,某些编译器可能将 int 定义为 16 位或 64 位),如果将来换了编译器或平台,只需更改 typedef 的定义,而不必在代码库中搜索和替换每个变量定义,代码维护更加容易。

③定义变量时更加方便

不用每次都写 unsigned char、unsigned short 和 unsigned int。

2.2用于结构体

我们可以通过以下方式创建结构体。

struct USART_InitTypeDef
{
  uint32_t USART_BaudRate;        
  uint16_t USART_WordLength;        
  uint16_t USART_StopBits;     
  uint16_t USART_Parity;         
  uint16_t USART_Mode;           
  uint16_t USART_HardwareFlowControl;  
};

//定义结构体变量
struct USART_InitTypeDef stu_usart;

不过这种方式,每次定义结构体变量都要加struct .....,比较麻烦。

所以,我们可以用typedef关键字给结构体创建一个别名。

typedef struct
{
  uint32_t USART_BaudRate;        
  uint16_t USART_WordLength;        
  uint16_t USART_StopBits;     
  uint16_t USART_Parity;         
  uint16_t USART_Mode;           
  uint16_t USART_HardwareFlowControl;  
} USART_InitTypeDef;

//定义结构体变量
USART_InitTypeDef stu_usart;

使用typedef给结构体创建了别名USART_InitTypeDef,下次就可以直接使用USART_InitTypeDef去定义结构体变量,不用再写struct了,这样代码更加方便简洁。

这种方式,在STM32之类的库文件里,有海量的使用。

2.3用于枚举

typedef enum
{ 
    GPIO_Mode_AIN = 0x0,
    GPIO_Mode_IN_FLOATING = 0x04,
    GPIO_Mode_IPD = 0x28,
    GPIO_Mode_IPU = 0x48,
    GPIO_Mode_Out_OD = 0x14,
    GPIO_Mode_Out_PP = 0x10,
    GPIO_Mode_AF_OD = 0x1C,
    GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

//定义枚举变量
GPIOMode_TypeDef GPIO_Mode;

这段代码定义了一个枚举类型,使用 typedef 关键字,这个枚举类型被赋予了一个别名GPIOMode_TypeDef,下次需要定义该枚举类型变量时,可直接使用GPIOMode_TypeDef xx,这样代码可读性更高,也简洁。

这种方式,在实际产品中,也是用的非常多嘀。

2.4用于函数指针

我们先来看看不用typedef的函数指针创建方法:

//代码示例1,不用typedef的函数指针

// 定义一个函数,形参为无符号字符类型,无返回值。
void KeyEventHandle1(unsigned char keys)
{
    //功能实现
}

void KeyEventHandle2(unsigned char keys)
{
    //功能实现
}

//定义了一个函数指针 KeyEvent_CallBack_t,并将KeyEventHandle函数的地址赋给它。
void (*KeyEvent_CallBack_t1)(unsigned char) = KeyEventHandle1;
void (*KeyEvent_CallBack_t2)(unsigned char) = KeyEventHandle2;

这种方式,如果需要重复去定义同样的函数指针,是比较麻烦的,每次定义函数指针变量都要写void (*函数指针变量名)(形参1)......

下面来看看用typedef创建函数指针。

//使用了typedef定义函数指针类型KeyEvent_CallBack_t
typedef void (*KeyEvent_CallBack_t)(unsigned char keys);

void KeyEventHandle1(unsigned char keys)
{
    //功能实现
}

void KeyEventHandle2(unsigned char keys)
{
    //功能实现
}


KeyEvent_CallBack_t KeyScanCBS1 = KeyEventHandle1;
KeyEvent_CallBack_t KeyScanCBS2 = KeyEventHandle2;

很明显,我们可以用KeyEvent_CallBack_t 这个函数指针类型,直接定义函数指针变量,这样比不用typedef的方式要方便简洁很多,特别是对于那些形参多的函数。

这种方式,我自己做产品时用的很多,我们无际项目特训营的项目3和6都有挺多这种应用。

以上,是我做产品接触最多的几种用法,还有其它的,比如typedef+数组,typedef+联合体,我个人用的比较少。

用法基本万变不离其宗,掌握这几种,看到其它的也基本能融会贯通。

3.typedef的优势总结

我们来总结下,typedef最主要的几点优势:

  • 提高代码可读性:通过使用有意义的类型名,代码更易于理解。

  • 简化复杂类型:对于结构体、枚举、函数指针等复杂类型,使用 typedef 可以简化变量定义。

  • 易于修改:如果基本类型需要更改,只需更改 typedef 定义,而不必修改使用该类型的所有实例。

  • 增加代码移植性:不同编译器或平台可能对某些数据类型的大小有差别(例如,int在某些平台上可能是16位,在另一些平台上可能是32位或64位)。通过使用 typedef,可以在不同的平台上定义相同的名字来代表具有适当大小和对齐的数据类型。


最近很多粉丝问我单片机怎么学,我根据自己从业十年经验,累积耗时一个月,精心整理一份「单

片机最佳学习路径+单片机入门到高级教程+工具包」全部无偿分享给铁粉!!!

除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,让你迅速进阶成高手

教程资料包和详细的学习路径可以看我下面这篇文章的开头

《单片机入门到高级开挂学习路径(附教程+工具)》

《单片机入门到高级开挂学习路径(附教程+工具)》

《单片机入门到高级开挂学习路径(附教程+工具)》

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

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

相关文章

artts升级版本后常见的编译错误(定期更新......)

1、设置泛型将参数配置为 null 时抛出了如下异常: Type null is not assignable to type T. T could be instantiated with an arbitrary type which could be unrelated to null. <ArkTSCheck> 解决办法 在 null 后面添加 ! 即可,以表示该值不会为 null data: T null!…

【可能是全网最丝滑的LangChain教程】十七、LangChain进阶之Retrievers

人生不能像做菜&#xff0c;把所有的料都准备好了才下锅。 01 Retrievers介绍 检索器&#xff08;Retrievers&#xff09; 是一种接口&#xff0c;用于根据非结构化查询返回文档&#xff0c;它比向量存储更为通用&#xff0c;既可以使用向量存储作为底层&#xff0c;也可以是其…

C++11右值引用及移动构造

区分左值和右值 在学习c11的右值引用前&#xff0c;大家肯定会有点陌生什么是右值&#xff1f;什么是左值&#xff1f;现在我先来带大家熟悉一下概念。 左值 可以被取地址&#xff0c;也可被修改&#xff08;const修饰的除外&#xff09; 可以出现在等号左边&#xff0c;也可…

华为HCIP Datacom H12-821 卷29

1.多选题 下面关于LSA age字段&#xff0c;描述正确的是∶ A、LSA age的单位为秒&#xff0c;在LSDB中的LSA的LS age随时间增长而增长 B、LSA age的单位为秒&#xff0c;在LSDB中的LSA的LS age随时间增长而减少 C、如果一条LSA的LS age达到了LS RefreshTime&#xff08…

【C++】AVL树(旋转、平衡因子)

&#x1f308;个人主页&#xff1a;秦jh_-CSDN博客&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12575764.html?spm1001.2014.3001.5482 ​ 目录 前言 AVL树的概念 节点 插入 AVL树的旋转 新节点插入较高左子树的左侧---左左&#xff1a;…

Spring的AOP基础以及AOP的核心概念

2. AOP基础 学习完spring的事务管理之后&#xff0c;接下来我们进入到AOP的学习。 AOP也是spring框架的第二大核心&#xff0c;我们先来学习AOP的基础。 在AOP基础这个阶段&#xff0c;我们首先介绍一下什么是AOP&#xff0c;再通过一个快速入门程序&#xff0c;让大家快速体…

高级RAG检索中的五种查询重写策略_用于检索增强的大型语言模型的查询重写

一、前言 检索增强生成 (RAG) 作为人工智能 (AI) 领域的一项重要技术&#xff0c;近年来得到了飞速发展。它将基于检索模型和基于生成的模型相结合&#xff0c;利用海量外部数据&#xff0c;生成更具信息量、更准确、更具语境相关性的回复。检索策略是 RAG 系统的关键组成部分…

2024年最适合高级网工的11款Linux

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 你们好&#xff0c;我的网工朋友。 Linux作为一个免费且开源的操作系统&#xff0c;随着时间的推移催生了多个发行版&#xff0c;并且得到了庞大…

golang验证Etherscan上的智能合约

文章目录 golang验证Etherscan上的智能合约为什么要验证智能合约如何使用golang去验证合约获取EtherscanAPI密钥Verify Source Code接口Check Source Code Verification Status接口演示示例及注意事项网络问题无法调用Etherscan接口&#xff08;最重要的步骤&#xff09; golan…

应用层协议原理——因特网提供的运输服务

我们已经考虑了计算机网络能够一般性地提供的运输服务。现在我们要更为具体地考察由因特网提供的运输服务类型。因特网(更一般的是TCP/IP网络)为应用程序提供两个运输层协议&#xff0c;即UDP和TCP。当软件开发者为因特网创建一个新的应用时&#xff0c;首先要做出的决定是&…

js逆向案例 | 加速乐反爬逆向

前言 加速乐作为一种常见的反爬虫技术&#xff0c;在网络上已有大量详尽深入的教程可供参考。然而&#xff0c;对于那些初次接触的人来说&#xff0c;直接面对它可能仍会感到困惑。 声明 本文仅用于学习交流&#xff0c;学习探讨逆向知识&#xff0c;欢迎私信共享学习心得。如…

收银系统源码-商品报损管理

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

ESXi6.7 update 3主机实现新硬件运行老环境

server 2003 SQL server 2000 SQL SP4 vmware tools 一、适用场景 1、运行多年的老企业&#xff0c;积累的数据量庞大&#xff0c;其中的数据库并不一定都是现在开发的平台或系统&#xff0c;而是已经正在运行&#xff0c;不能停业务的状态。 2、老系统老应用平台&#xf…

day01:项目概述,环境搭建

文章目录 软件开发整体介绍软件开发流程角色分工软件环境 外卖平台项目介绍项目介绍定位功能架构 产品原型技术选型 开发环境搭建整体结构&#xff1a;前后端分离开发前后端混合开发缺点前后端分离开发 前端环境搭建Nginx 后端环境搭建熟悉项目结构使用Git进行版本控制数据库环…

Day06-01-lvs

Day06-01-lvs 0. 核心内容1.负载均衡项目 选择故障: 2.lvs 预备姿势-arp3.lvs 概述4. lvs工作模式4.1 预备姿势4.2 lvs-dr模式4.3 lvs-nat模式4.4 小结 5. lvs-dr模式5.1 环境准备5.2 lvs-dr模式配置流程1) lvs服务端配置2) web服务器 RS服务端配置3) 小结4) 调试 5.3 抓包查看…

电脑清理软件用哪个好?这款工具有些饱受争议

电脑清理软件用哪个好?电脑作为我们工作和娱乐的重要工具&#xff0c;其运行速度和安全性直接影响着我们的生活质量。然而&#xff0c;随着时间的推移&#xff0c;电脑系统会积累大量垃圾文件、注册表错误、恶意软件等&#xff0c;导致电脑运行缓慢甚至崩溃。 这时&#xff0c…

el-tree 获取当前勾选节点的选中状态以及选中值对象 触发check-change多次事件问题原因

1.需求 现在需要一个树状结构的资产树 但是现在需求是 获取当前选中的值的状态是选中还是取消选中 然后再用当前选中 or 取消选中的值 进行 选中 or 取消选中的操作 一开始使用的是 check-change 方法 接收参数如图 但是我勾选父节点 或者 子节点后 他会打印一堆数据 是因…

基于Java+SpringMvc+Vue技术的智慧校园系统设计与实现

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

昇思25天学习打卡营第11天 | LLM原理和实践:基于MindSpore实现BERT对话情绪识别

1. 基于MindSpore实现BERT对话情绪识别 1.1 环境配置 # 实验环境已经预装了mindspore2.2.14&#xff0c;如需更换mindspore版本&#xff0c;可更改下面mindspore的版本号 !pip uninstall mindspore -y !pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore2.2…

geospy.AI 根据图片定位地理位置

文章目录 简介场景标志性建筑平凡的商店名标志性的物品标志性的地理位置标志性的街道难以分辨的古建筑不出名的山水 简介 GeoSpy.ai 作为一个地理空间情报平台&#xff0c;可以在以下场景中使用&#xff1a; 农业&#xff1a;监控农作物生长情况&#xff0c;预测产量&#xf…