C++数据结构——结构体与联合体

结构体

定义

使用结构体时,用户可以自定义数据类型,在一个结构体的定义中,可以在自定义数据类型中定义一个或多个已定义的数据类型。例如int、long long、double、或其他自定义的数据类型等等。一个基本的结构体的定义例如:

struct S{
	int a;
	char ch;
	double f;
	// 包含的变量
	void read(){
		cin>>a>>ch>>f;
	}
	// 也可以在结构体中包含函数
};// 注意不要忘记了这里的分号
S s[100];	// 定义S类型数组

__ 结构体的核心特性: __

  • 数据聚合:将逻辑相关的多个数据项组合在一起

  • 成员多样性:可以包含任意类型的成员(基本类型、数组、指针、其他结构体等)

  • 默认公开性:成员默认是public访问权限(与class的private默认不同)

  • 内存连续性:成员在内存中按声明顺序连续排列(可能有填充字节)

高级用法

位域(Bit Fields):

允许指定成员占用的位数,常用于硬件编程和协议设计:

struct StatusRegister {
    unsigned int error : 1;   // 1位
    unsigned int ready : 1;   // 1位
    unsigned int mode : 2;    // 2位
    unsigned int : 4;         // 未使用的4位
    unsigned int value : 8;   // 8位值
};

柔性数组(Flexible Array Member):

C99引入的特性,允许结构体包含大小不确定的数组(必须是最后一个成员):

struct DynamicString {
    int length;
    char data[]; // 柔性数组成员
};

联合体

定义

联合体是一种特殊的数据类型,允许在同一内存位置存储不同的数据类型。所有成员共享同一块内存空间,其大小由最大成员决定。

关键特性

  • 内存共享:所有成员占用同一内存区域
  • 瞬时单一性:任何时候只能有一个成员包含有效值
  • 大小决定:联合体大小等于其最大成员的大小(考虑对齐)
  • 类型转换:可视为隐式的类型转换机制

联合体的典型应用场景

类型转换

union Converter {
    float f;
    unsigned int i;
    char bytes[4];
};

Converter c;
c.f = 3.14f;
// 现在可以通过c.i或c.bytes访问float的二进制表示

变体记录(Variant Records)
表示可能具有多种形式的数据:

union Variant {
    int intVal;
    double doubleVal;
    char* stringVal;
};

协议解析
解析网络协议或文件格式时,同一内存区域可能包含不同类型的数据:

union IPAddress {
    uint32_t address;
    uint8_t octets[4];
};

联合体的限制与风险

主要限制

  • 不能包含引用类型的成员
  • 不能继承或被继承
  • C++11前不能包含有非平凡构造函数的成员(如std::string)

使用风险

  • 类型混淆:错误访问非当前活跃成员导致未定义行为
  • 构造/析构问题:需要手动管理复杂类型的生命周期
  • 可移植性问题:字节序(Endianness)问题影响跨平台使用

结构体与联合体的对比分析

特性结构体(struct)联合体(union)
内存使用各成员有独立存储空间所有成员共享存储空间
存储大小所有成员大小之和(含填充)最大成员的大小
成员访问可同时访问所有成员同一时间只能访问一个成员
默认访问控制publicpublic
构造函数支持C++11起支持
继承支持不支持
典型用途数据聚合类型转换、变体记录

结构体和联合体作为C++的基础复合数据类型,在很多领域仍有不可替代的价值。理解它们的底层机制和适用场景,能够帮助开发者编写出更高效、更贴近硬件的代码。在现代C++开发中,虽然一些新特性(如std::variant)提供了更安全的替代方案,但在需要精细控制内存布局或与C代码交互的场景中,传统结构体和联合体仍然是重要工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值