嵌入式-C语言-江科大-数据类型宏定义#define关键字typedef结构体

这是C语言中高级相关知识,在单片机中实战的一些用法
参考C语言江科大视频的学习笔记,详细举例子并且完整记录up的想法,包括内容有c语言数据类型&宏定义#define&关键字typedef&结构体&预处理指令

文章目录

    • 一:C语言数据类型
    • 二:宏定义 #define
    • 三:关键字typedef
    • 四:结构体
    • 五:枚举类型
    • 六:预处理指令
      • 道友:与其仰望他人,不如埋头奋斗。

一:C语言数据类型

关键字位数表示范围stdint关键字ST关键字
char8-127-128int_8s8
unsigned char80-255uint8_tu8
short16-32768~32767int16_ts16
unsigned short160~65535uint16_tu16
int32-2147483648~2147483647int32_ts32
unsigned int320~4294967295uint32_tu32
long32-2147483648~2147483647
unsigned long320~4294967295
long long64-(2^ 64)/2~(2^64)/2-1int64_t
unsigned long long640~(2^64)-1uint64_t
float32-3.4e38~3.4e38
double64-1.7e308 ~ 1.7e308
  • 51单片机中int型为16位;stm32中int型为32位。
  • 倒数第二列是C语言给这些类型提供的别名;所以最后一列是老版本ST公司库函数给这些类型提供的别名,新版的库函数已经全部替换成倒数第二列。所以以后尽量使用倒数第二列。

二:宏定义 #define

关键字#define,主要用于:用一个字符串代替一个数字,便于理解,防止出错;或者提取程序中经常出现的参数,便于快速修改。俗称叫外号。

//定义宏定义:
#define ABC 12345
//引用宏定义:
int a = ABC;//相当于int a = 12345;

在这里插入图片描述

  • 相当于GPIO_InitStructure.GPIO_Pin = ((uint16_t) 0x1000)经过宏定义变成GPIO_InitStructure.GPIO_Pin =GPIO_Pin_12;

  • 在C里面,宏定义定义在主函数外面,并且如果给一个变量宏定义一个值,那么程序里面出这个变量都是这个值,并且是不可修改的

三:关键字typedef

关键字typedef,目的将一个比较长的变量类型名换个比较短的变量类型名,便于使用。
因为结构体变量类型较长,所以通常用typedef更改变量类型名。

//定义typedef:
typedef unsigned char uint8_t;
//引用typedef:
uint8_t num1; //等效于unsigned char num1;
  • 相比于#define(不用加分号) 来说,typedef(必须加分号)在进行改名时会进行变量类型检查,如果不是变量类型的名字那是不行的,所以更加安全。
  • 宏定义任何名字都可以换,而typedef只能专门给变量类型换名字。

四:结构体

关键字 struct ,用途:数据打包,是不同类型变量的集合

  • struct c;//一个叫做c的结构体里面有{}
  • struct {char x;int y;float z;}; c; //一个叫做c的结构体里面有{char x;int y;float z;}
//在main函数中定义结构体变量:
struct{      //相当于struct{ int a;} StructName;
	char x;
	int y;
	float z;
}StructName1;
//因为结构体变量类型(结构体也是一个变量类型)较长,
//所以通常在mian函数外用typedef更改变量类型名
typedef  struct{   //相当于(typedef A  a),我把长的变量类型A变为短的变量类型a
	char x;
	int y;
	float z;
}StructName_t; //相当于(typedef struct{}  StructName_t),
				//我把长的变量类型名字struct{}变为短的变量类型名字StructName_t

//引用结构体成员:方法一用‘.’
StructName_t struct1;//我把长的变量类型名字struct{}变为短的变量类型名字StructName_t
//相当于数据类型+变量名字  int a;
struct1.x='A';
struct1.y = 66;
struct1.z = 1.23;
//引用结构体成员:方法二“->”
pStructName ->x = 'A';  //结构体指针名,pStructName为结构体的地址
pStructName ->y = 66;
pStructNmae ->z = 1.23;
  • 数组char a[10]里面有10个char类型的数组元素,都是相同类型的,但我们需要组合10个不同数据类型的呢,那我们可以用结构体,结构体就是不同数据类型的集合。
  • 数组、结构体、共用体、枚举都是构造数据类型
  • 如下图,先定义再引用,int a;a =10;都是数据类型+名字
    在这里插入图片描述在这里插入图片描述

五:枚举类型

关键字enum,enumerate枚举
用途:定义一个取值 受限制的整型变量,也用于限制变量取值范围;
枚举也相当于一个宏定义的集合,可以直接把里面的枚举变量拿出来用。注意枚举变量用逗号隔开,且最后一个枚举变量不加逗号。

//函数内定义枚举变量:
enum{    //enum {} EnumName;
		FALSE = 0,
		TRUE = 1
}EnumName;
//因为枚举变量类型较长,所以通常在函数外用typedef更改变量类型名
typedef enum{
FALSE = 0;
TRUE = 1
}EnumName;

//引用枚举成员:
EnumName emu1;
emu1 =  FLASE;
emu1 =  TRUE;

下图的图一和图二是等价的
在这里插入图片描述在这里插入图片描述

六:预处理指令

#ifndef、#define 和 #endif 来确保头文件只被编译一次。

#ifndef __DELAY_H   //这是预处理指令,用来判断某个宏是否已经定义,如果该宏(没有)定义,则执行下面的代码
#define __DELAY_H  //宏定义

void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

#endif

当一个头文件(例如delay.h)被多个源文件引用时,可以使用预处理指令 #ifndef、#define 和 #endif 来确保头文件只被编译一次。

#ifndef 预处理指令:
#ifndef 是 “if not defined” 的简写。
#ifndef 用于检查某个宏是否未定义。如果该宏未定义,则执行下面的代码。
如果宏已经定义过了,#ifndef 中的代码将被忽略。

举例子说明:
#endif 是C/C++中的预处理指令,用于结束条件编译块。

当在代码中使用 #ifdef#ifndef#if 这些条件编译指令时,需要使用 #endif
来标记条件编译块的结束位置。

例如,以下是一个简单的条件编译示例:

#ifdef DEBUG_MODE
    // 调试模式下执行的代码
    printf("Debug mode is enabled.\n");
#else
    // 正常模式下执行的代码
    printf("Debug mode is disabled.\n");
#endif 

在这个示例中, #ifdef DEBUG_MODE  判断是否定义了  DEBUG_MODE
宏。如果定义了该宏,则执行调试模式下的代码;否则,执行正常模式下的代码。

最后的 #endif 指令用于标记条件编译块的结束位置。它表示上面的条件编译块已经结束,之后的代码将会被正常编译。

总结来说, #endif  用于结束条件编译块,它与  #ifdef 、 #ifndef  或  #if 
一起使用,确保条件编译的范围正确闭合。

参考:B站STM32江协自动化&【哈工大虎慕】

道友:与其仰望他人,不如埋头奋斗。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

idea 折叠某段代码 这段特定某段代码

如何折叠IntelliJ IDEA代码片段_w3cschool ctrlALTT

HNU-数据挖掘-作业1

数据挖掘课程作业作业1 计科210X 甘晴void 202108010XXX 第一题 假设所分析的数据包括属性 age,它在数据元组中的值(以递增序)为13 ,15 ,16 ,16 ,19 ,20 ,20 ,21 ,22 ,22 ,25 ,25 ,25 ,25 ,30 ,33 ,33 ,35 ,35 ,35 ,35 ,36 ,40 ,45 ,46 ,52,70。 a.…

从零开始的OpenGL光栅化渲染器构建5-阴影

前言 阴影是光线被阻挡的结果;当一个光源的光线由于其他物体的阻挡不能够达到一个物体的表面的时候,那么这个物体就在阴影中了。阴影能够使场景看起来真实得多,并且可以让观察者获得物体之间的空间位置关系。 直接阴影 阴影映射(Shadow Ma…

C语言/c++指针详细讲解【超详细】【由浅入深】

指针用法简单介绍 指针,是内存单元的编号。 内存条分好多好多小单元,一个小单元有 8 位,可以存放 8 个 0 或 1;也就是说,内存的编号不是以位算的,而是以字节算的,不是一个 0 或 1 是一个编号&…

【题目】2023年国赛信息安全管理与评估正式赛任务书-模块3 CTF

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 任务书 模块三 网络安全渗透、理论技能与职业素养 竞赛相关资源资料可在文末关注公众号获得 比赛时间及注意事项 本阶段比赛时长为180分钟,时间为9:00-12:00。 【注意事项】 (1&#xf…

做一个简单的倒计时

<div>距离过年还有:<span></span></div><script>let div document.querySelector("div");let span document.querySelector("span");// 获取未来时间戳let future new Date("2024-2-10 00:00:00");// 获取当下…

深度解析Python关键字:掌握核心语法的基石(新版本35+4)

目录 关键字 keyword 关键字列表 kwlist softkwlist 关键字分类 数据类型 True、False None 运算类型 and、or、not in is 模块导入 import 辅助关键字 from、as 上下文管理 with 占位语句 pass 流程控制 if、elif、else for while break、continue…

Android学习之路(23)组件化框架ARouter的使用

一、功能介绍 支持直接解析标准URL进行跳转&#xff0c;并自动注入参数到目标页面中支持多模块工程使用支持添加多个拦截器&#xff0c;自定义拦截顺序支持依赖注入&#xff0c;可单独作为依赖注入框架使用支持InstantRun支持MultiDex(Google方案)映射关系按组分类、多级管理&…

计组原理:系统概论与基本组成

系统概论与基本组成 系统概论硬件软件 计算机系统的层次结构系统复杂性的管理方法1&#xff1a;抽象 计算机的基本组成冯诺依曼计算机系统复杂性的管理方法 2&#xff1a;&#xff08;3’Y&#xff09; 计算机的工作步骤上机前的准备&#xff1a;计算机的解题过程存储器的基本组…

Java List集合使用 Comparator.comparing 排序报空指针异常问题

前言 有时候对一个List集合的某个字段进行排序的时候会报错&#xff0c;问题就是排序的那个字段可能是个空值&#xff0c;那么下面就是处理这种问题的方式&#xff0c;亲自测试有效。 参考 点击可跳转&#xff1a;Java List集合使用 Comparator.comparing 排序报空指针异常问…

TPM模拟器安装

目录 TPM模拟器安装 1&#xff09;安装配置所需依赖 2&#xff09;从官网下载TPM模拟器程序ibmtpm1332.tar.gz 3&#xff09;创建安装目录并将源码解压到对应目录 4&#xff09;进入解压后的目录&#xff0c;然后执行安装命令 5&#xff09;将tpm服务器添到Linux系统执行目…

gradle各版本下载地址

IDEA如何配置 Gradle&#xff08;详细版&#xff09;_idea gradle配置-CSDN博客 Gradle | Releases 参考以上文档

Python中函数的4种参数形式

默认参数的特点是在声明函数时使用“”来指定默认值。缺省参数指因为程序使用了默认值&#xff0c;使得函数调用时不必写出全部参数。 关键字参数可以摆脱位置匹配的限制&#xff0c;直接用变量名匹配。可变参数用于处理任意数量的参数&#xff0c;形参中带一个*&#xff0c;将…

小蓝和小桥的挑战*

题目 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int t sc.nextInt();sc.nextLine();while(t-- > 0) {int n sc.nextInt();sc.nextLine();int[] a new int[n];for(int i0;i<n;i)a[i…

Web server failed to start.Port xxxx was already in use.

目录 一、报错截图&#xff1a;二、解决方式 一、报错截图&#xff1a; 某端口被占用,导致出现如下报错&#xff1a; 二、解决方式 windowsR 输入cmd—>回车 如下图所示 查看被占用的端口的进程&#xff0c;如下图&#xff1a; netstat -ano |findstr 端口号结束这个进程…

恭喜CSDN,www.csdn.com域名买回来了!

摘要&#xff1a;www.csdn.com已经可以访问了&#xff0c;恭喜CSDN&#xff0c;迈出国际化的重要一步。 主页面浓浓的国际简约范 静态展示特点 著名的1024 day day up OpenStack & Open-Source 最后附上的是report 已经有众多支持者了&#xff0c;看排序。 博客不多&#…

重拾计网-第三弹 你不知道的计算机的秘密

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾计算机网络 &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错…

【MATLAB源码-第120期】基于matlab的GFSK系统调制解调仿真,输出各个节点的波形以及功率谱。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 GFSK&#xff08;高斯频移键控&#xff09;是一种数字调制技术&#xff0c;广泛应用于无线通信领域&#xff0c;尤其是在低功率和短距离通信系统中&#xff0c;例如蓝牙技术。GFSK是频移键控&#xff08;FSK&#xff09;的一…

Vue3+ElementUI 多选框中复选框和名字点击方法效果分离

现在的需求为 比如我点击了Option A &#xff0c;触发点击Option A的方法&#xff0c;并且复选框不会取消勾选&#xff0c;分离的方法。 <el-checkbox-group v-model"mapWork.model_checkArray.value"> <div class"naipTypeDom" v-for"item …

AI+量化02_金融市场的基础概念

文章目录 问答之纯小白 vs GPT4Q1. 请用尽可能简短的语句或例子&#xff0c;给小白讲解宏观经济Q2. 给小白讲解资本边际效率Q3. 如果证券没有风险是否意味着没有收益&#xff1f;Q4. 芒格&#xff1a;教人炒股&#xff0c;犹如引人吸毒Q5. 给小白快速讲解&#xff1a;卡房统计量…