HaveFunWithEmbeddedSystem/Chapter2 C与C++/2.6 结构体与联合体.md

113 lines
2.8 KiB
Markdown
Raw Normal View History

# 2.6 结构体与联合体
2018-03-21 23:37:47 +08:00
## 2.6.1 结构体
数组中保存的是一组相同类型的数据,而结构体中可以保存一组不同类型的数据,他是一类数据的聚合。
```cpp
// 元素 A 和 B 占用不同存储空间.
struct _A_STRUCT
{
short A; // 内部元素 A.
char B; // 元素 B.
int C; // 元素 C.
}AStruct = {15, 8, 32};
struct _A_STRUCT* pAStruct = &AStruct; // pAStruct 是一个结构体指针.
printf("%d\n", sizeof(AStruct)); // AUnion 的长度为 8涉及到内存对齐.
printf("A=%d\n", AStruct.A); // 输出 15.
printf("B=%d\n", pAStruct->B); // 输出 8.
```
结构体变量使用 “.” 来访问内部元素,而结构体指针使用 “->” 来访问内部元素。
我们看到,上面定义结构体指针的方法非常繁琐,我们有更简单的方式:
```cpp
struct _A_STRUCT
{
short A;
char B;
int C;
}A_STRUCT; // 通过 typedef 将 A_STRUCT 定义成了 struct _A_STRUCT 类型.
A_STRUCT AStruct = {15, 8, 32}; // 这样用起来就方便了.
A_STRUCT* pAStruct = &AStruct; // 嗯,确实方便多了.
```
## 2.6.2 联合体
联合体则为同一地址空间起了两或多个名字。
```cpp
// 元素 A 和 B 占用同一存储空间.
union _A_UNION
{
short A;
char B;
}AUnion;
printf("%d\n", sizeof(AUnion)); // AUnion 的长度为 2.
```
访问联合体内部元素的方法与结构体类似。
联合体也支持 typedef方法与结构体一致。
## 2.6.3 结构体、联合体混合使用
结构体中可以嵌套联合体:
```cpp
typedef struct _SuperHero
{
char* name;
char* actor;
union
{
unsigned short ShieldLevel;
unsigned short IronLevel;
}; // 结构体中允许使用匿名联合体.
}SuperHero;
void InitSuperHero(SuperHero* hero)
{
if(0==strcmp("Captain America", hero->name))
{
hero->ShieldLevel = 3;
}
else if(0==strcmp("Iron Man", hero->name))
{
hero->IronLevel = 4;
}
}
```
除了结构体嵌套联合体外,还允许结构体嵌套结构体、联合体嵌套联合体、联合体嵌套结构体等,由此可以组合成复杂的数据结构。
## 2.6.4 结构体、联合体、数组混合使用
可以创建结构体数组,联合体数组,或更加复杂数据结构类型的数组。
```cpp
typedef struct _SuperHero
{
char* name;
char* actor;
union
{
unsigned short ShieldLevel;
unsigned short IronLevel;
}; // 结构体中允许使用匿名联合体.
}SuperHero;
SuperHero MarvelHeros[8000]; // 听说漫威有 7000 多个超级英雄,多余空位预留吧!
MarvelHeros[0].name = "Black Widow";
MarvelHeros->actor = "Scarlett Johansson";
```
## 2.6.5 结构体与内存对齐
## 练习