C语言中struct、enum和union的类型概述是什么?
摘要:本文作为前导内容,主要为后续的详细介绍做铺垫,简要介绍了 struct、enum 和 union 三种类型的基本概念,并对它们在实际应用中的典型组合方式进行了简单说明。
一、前导
在实际工程中,当数据不再是单个标量,而是一个“对象”、“帧”、“配置”或“状态集合”时,我们就需要使用一种能把这些数据按照语义组织起来、按字节布局落到内存里并且便于维护与传递的表达方式。而在C语言中,struct/enum/union这些复合类型就是为这个目的服务的。
所以在C语言中复合数据类型就是由一个或多个基本类型(或其他复合类型)组合而成的新类型,并且以连续内存块的形式存储,通常用来表示更复杂的数据结构。下面我将对struct、enum、union这三种类型进行简要介绍。
二、struct
在嵌入式开发中,经常会遇到这样一种情况:某个功能往往不是由一个单独的数据完成的,而是由一组彼此关联的数据共同描述。例如:一个参数节点通常包含参数编号、当前值、属性标志等信息;一条通信报文可能包含标识符、数据长度和数据区;一个外设配置结构中也往往包含多个配置。如果这些数据分别用独立变量进行管理,不仅会造成代码分散,在函数传参和模块之间交互时也会变得不直观;
为了解决此类问题,C语言提供了struct关键字,用于将多个相关的数据组织成一个整体,使数据的含义更加清晰,同时也便于统一管理和传递。在嵌入式项目中,结构体常用与描述参数对象、通信帧、设备状态以及各种配置结构,是数据建模中最常用的手段之一。
基本语法形式:
方式一:
struct tag{
member-list1;
member-list2;
member-list3;
...
}variable_one;
struct tag variable_two;
struct tag variable_three;
方式二:
struct tag{
member-list1;
member-list2;
member-list3;
...
};
struct tag variable_one;
struct tag variable_two;
struct tag variable_three;
在结构体的定义过程中,通常可以理解为两个步骤:
第一步是定义结构体类型,即定义 struct tag ;
第二步就是定义该类型的变量 variable_one 。然后我们就可以通过这些变量对结构体中的成员进行访问和操作。
在方式一和方式二中,本质区别在于是否将“定义类型”和“定义变量”这两个步骤写在同一处。方式一将两步合并在一起,写法更加紧凑,但同时也提高了类型定义与变量定义之间的耦合度。当后续需要维护或复用该结构体类型时,容易让人误以为该结构体仅用于 variable_one,从代码阅读和组织角度来看不够清晰。
方式二将类型定义与变量定义分离,使结构体类型的复用更加直观,也更符合实际工程中类型与变量分开管理的习惯,因此在嵌入式项目中更为常见。
三、enum
在C语言中,enum(枚举)是一种常用于定义一组具有明确含义的整数常量,常用来表示状态、类型或模式,使代码逻辑更加清晰和易于维护。
基本语法形式:
enum 枚举名{
枚举元素1,
枚举元素2,
枚举元素3,
...
};
enum 枚举名 variable;
在对枚举的定义过程中,也可以分为两个步骤:
第一步是定义枚举类型,也就是定义枚举名;
第二步是定义该类型的变量 variable。
其中第二步是否有必要取决于工程需求,比如枚举只是用来做返回值、错误码或函数参数等这些情况就不需要定义枚举变量,也就是不需要执行第二步。
总的来说,枚举常量本质上还是整数常量,而枚举变量则用于保存当前的枚举值,所以enum也常常与状态变量或配置变量配合使用。
四、union
union(共用体、联合体)是一种特殊的数据结构,它允许在同一内存位置存储不同类型的数据。union与struct不同,struct内的每个成员都会占用不同的内存空间,而union内的所有成员则是共享同一块内存空间,这也就意味着在任何时刻,union只能包含一个成员的值。
方式一:
union tag{
member-list1;
member-list2;
member-list3;
...
}variable_one;
方式二:
union tag{
member-list1;
member-list2;
member-list3;
...
};
union tag bariable_one;
union的定义过程与struct基本一致,同时第二步是否选择也可以参考struct。
