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

这是C语言中高级相关知识,在单片机中实战的一些用法

参考C语言江科大视频的学习笔记,详细举例子并且完整记录up的想法,包括内容有c语言数据类型&宏定义#define&关键字typedef&结构体&预处理指令

文章目录

一:C语言数据类型

关键字 位数 表示范围 stdint关键字 ST关键字
char 8 -127-128 int_8 s8
unsigned char 8 0-255 uint8_t u8
short 16 -32768~32767 int16_t s16
unsigned short 16 0~65535 uint16_t u16
int 32 -2147483648~2147483647 int32_t s32
unsigned int 32 0~4294967295 uint32_t u32
long 32 -2147483648~2147483647
unsigned long 32 0~4294967295
long long 64 -(2^ 64)/2~(2^64)/2-1 int64_t
unsigned long long 64 0~(2^64)-1 uint64_t
float 32 -3.4e38~3.4e38
double 64 -1.7e308 ~ 1.7e308
  • 51单片机中int型为16位;stm32中int型为32位。
  • 倒数第二列是C语言给这些类型提供的别名;所以最后一列是老版本ST公司库函数给这些类型提供的别名,新版的库函数已经全部替换成倒数第二列。所以以后尽量使用倒数第二列。

二:宏定义 #define

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

c 复制代码
//定义宏定义:
#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更改变量类型名。

c 复制代码
//定义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;}
c 复制代码
//在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枚举

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

c 复制代码
//函数内定义枚举变量:
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 来确保头文件只被编译一次。

c 复制代码
#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

来标记条件编译块的结束位置。

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

c 复制代码
#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江协自动化&【哈工大虎慕】

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

相关推荐
2501_9411444212 分钟前
Python + C++ 异构微服务设计与优化
c++·python·微服务
程序猿编码17 分钟前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince
charlie1145141911 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数
Cx330❀1 小时前
C++ STL set 完全指南:从基础用法到实战技巧
开发语言·数据结构·c++·算法·leetcode·面试
white-persist1 小时前
【攻防世界】reverse | Reversing-x64Elf-100 详细题解 WP
c语言·开发语言·网络·python·学习·安全·php
love530love1 小时前
【保姆级教程】Windows + Podman 从零部署 Duix-Avatar 数字人项目
人工智能·windows·笔记·python·数字人·podman·duix-avatar
zmzb01031 小时前
C++课后习题训练记录Day33
开发语言·c++
Want5952 小时前
C/C++贪吃蛇小游戏
c语言·开发语言·c++
草莓熊Lotso3 小时前
《算法闯关指南:动态规划算法--斐波拉契数列模型》--01.第N个泰波拉契数,02.三步问题
开发语言·c++·经验分享·笔记·其他·算法·动态规划
草莓熊Lotso4 小时前
Git 分支管理:从基础操作到协作流程(本地篇)
大数据·服务器·开发语言·c++·人工智能·git·sql