C语言中的struct结构体、union联合体、enum枚举和typedef
结构体struct
结构体是C编程中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。
结构体中的数据成员可以是基本数据类型(如 int、float、char等),也可以是其他结构体类型、指针类型等。
关键字:struct
struct结构体的一般格式如下:(引自:菜鸟教程)
struct tag {
member-list;
member-list;
member-list;
...
} variable-list ;
1. 结构体的定义
有以下几种不同的定义结构体的方式:
(1) 先定义结构体(显式定义),后定义结构体变量
struct set_of_mdata
{
int mdata1;
float mdata2;
char mdata3;
double mdata4[4];
};
struct set_of_mdata som1, som2; //定义结构体变量
(2) 定义结构体(显式定义)的同时定义结构体变量,还可以再次使用结构体声明变量
struct set_of_mdata
{
int mdata1;
float mdata2;
char mdata3;
double mdata4[4];
} som1, som2;
struct set_of_mdata som3;
(3) 定义结构体(隐式定义)的同时定义结构体变量,不可以再次使用结构体声明变量
struct
{
int mdata1;
float mdata2;
char mdata3;
double mdata4[4];
} som1, som2;
(4) 使用typedef
为结构体起别名(显式定义),通过别名定义结构体变量
typedef struct
{
int mdata1;
float mdata2;
char mdata3;
double mdata4[4];
} mdata_def;
mdata_def som1, som2;
2. 对结构体的一些操作
通过下面一段代码,来了解一下如何对结构体进行赋值和操作:
#include <stdio.h>
//定义结构体
struct set_of_mdata
{
int mdata1;
float mdata2;
char mdata3;
double mdata4[4];
};
struct set_of_mdata som = {10, 3.14, 'd', {2.0, 3.0, 4.0, 5.0}}; //在定义结构体变量时进行初始化
int main()
{
//通过.运算符访问或修改结构体成员
printf("mdata1:%d \n", som.mdata1);
printf("mdata2:%f \n", som.mdata2);
printf("mdata3:%c \n", som.mdata3);
printf("mdata4:%f \n", som.mdata4[2]);
//定义指向结构体的指针
struct set_of_mdata *mdata_ptr = &som;
//通过->运算符访问或修改结构体指针所指结构体的成员
mdata_ptr->mdata1 = 150;
mdata_ptr->mdata2 = 6.28;
printf("mdata1:%d \n", mdata_ptr->mdata1);
printf("mdata2:%f \n", mdata_ptr->mdata2);
}
输出结果如下:
知识点:
(1) 结构体成员的初始化
在定义结构体变量的同时,通过花括号{value1, value2,...}
赋给该结构体成员初始值。
(2) 访问结构体成员
通过.
运算符访问或修改结构体成员。
(3) 定义指向结构体的指针
和普通变量的指针定义方式相同。
(4) 结构体指针访问成员
通过->
运算符访问或修改结构体指针所指结构体的成员。
3. 结构体的大小
联合体union
联合体是类似结构体struct的一种数据结构,两者的区别在于联合体的成员共享同一个内存位置,也就是说,联合体中的所有成员都是从相同的内存地址开始。
一个union联合体只配置一个足够大的空间以来容纳最大长度的数据成员。
关键字:union
1. 联合体的定义
在定义上和结构体完全相同,将struct
关键字改为union
关键字即可。
(1) 先定义联合体(显式定义),后定义联合体变量
union udata
{
float ud1;
char ud2[3];
};
union udata udata1, udata2;
(2) 定义联合体(显式定义)的同时定义联合体变量,还可以再次使用联合体声明变量
union udata
{
float ud1;
char ud2[3];
}udata1, udata2;
union udata udata3;
(3) 定义联合体(隐式定义)的同时定义联合体变量,不可以再次使用联合体声明变量
union
{
float ud1;
char ud2[3];
}udata1, udata2;
(4) 使用typedef
为联合体起别名(显式定义),通过别名定义联合体变量
typedef union
{
float ud1;
char ud2[3];
}udata_def;
udata_def udata1, udata2;
2.对联合体的一些操作
操作与结构体的操作完全相同。参考对结构体的一些操作
一节。
3. 联合体的大小
枚举enum
枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读。
每个枚举常量可以用一个标识符来表示,也可以为它们指定一个整数值,如果没有指定,那么默认从 0
开始递增。
关键字:enum
枚举类型经常用于定义各种状态,用作函数的返回值,来指示函数的行为。
下面是STM32官方库的一些枚举类型的定义:
//GPIO Bit SET and Bit RESET enumeration
typedef enum
{
GPIO_PIN_RESET = 0U,
GPIO_PIN_SET
} GPIO_PinState;
//HAL ADC Callback ID enumeration definition
typedef enum
{
HAL_ADC_CONVERSION_COMPLETE_CB_ID = 0x00U, /*!< ADC conversion complete callback ID */
HAL_ADC_CONVERSION_HALF_CB_ID = 0x01U, /*!< ADC conversion DMA half-transfer callback ID */
HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID = 0x02U, /*!< ADC analog watchdog 1 callback ID */
HAL_ADC_ERROR_CB_ID = 0x03U, /*!< ADC error callback ID */
HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID = 0x04U, /*!< ADC group injected conversion complete callback ID */
HAL_ADC_INJ_QUEUE_OVEFLOW_CB_ID = 0x05U, /*!< ADC group injected context queue overflow callback ID */
HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID = 0x06U, /*!< ADC analog watchdog 2 callback ID */
HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID = 0x07U, /*!< ADC analog watchdog 3 callback ID */
HAL_ADC_END_OF_SAMPLING_CB_ID = 0x08U, /*!< ADC end of sampling callback ID */
HAL_ADC_MSPINIT_CB_ID = 0x09U, /*!< ADC Msp Init callback ID */
HAL_ADC_MSPDEINIT_CB_ID = 0x0AU /*!< ADC Msp DeInit callback ID */
} HAL_ADC_CallbackIDTypeDef
1. 枚举类型的定义
枚举类型的定义一般为:
enum 枚举类型 {枚举值1, 枚举值2, ......};
区别点:枚举类型花括号里的值是使用逗号,
分隔的,而结构体和联合体是使用;
分隔的。
(1) 先定义枚举类型(显式定义),后定义枚举变量
enum STATE
{
OK = 0 ,
WARN ,
ERROR ,
STOP
};
enum STATE mState;
(2) 定义枚举类型(显式定义)的同时定义枚举变量,还可以再次使用枚举类型声明变量
enum STATE
{
OK = 0 ,
WARN ,
ERROR ,
STOP
}mState1;
enum STATE mState2;
(3) 定义枚举类型(隐式定义)的同时定义枚举变量,不可以再次使用枚举类型声明变量
enum
{
OK = 0 ,
WARN ,
ERROR ,
STOP
}mState1;
(4) 使用typedef
为枚举类型起别名(显式定义),通过别名定义枚举变量
typedef enum
{
OK = 0 ,
WARN ,
ERROR ,
STOP
} STATE_DEF;
STATE_DEF mState1, mState2;
枚举类型中的枚举值的标识符是唯一的,不能与其他宏定义标识符重名。
2. 对枚举类型的一些操作
(1) 初始化枚举变量,在定义的时候进行初始化
typedef enum
{
OK = 0 ,
WARN ,
ERROR ,
STOP
} STATE_DEF;
STATE_DEF mState1 = WARN;
STATE_DEF mState2 = OK;
(2) 在程序当中修改枚举变量
typedef enum
{
OK = 0 ,
WARN ,
ERROR ,
STOP
} STATE_DEF;
STATE_DEF mState1 = WARN;
mState1 = OK; //在程序当中修改枚举变量