c进阶篇(五)——匿名结构体

前言:
  对c/c++程序员来说,结构体是非常常用的自定义数据类型,它对数据进行封装,使用匿名结构体可进一步增强数据的封装性。

1 什么是匿名结构体

  以下是正常定义一个带名称的结构体示范。

1
2
3
4
5
typedef struct Rect
{
Byte byLen;
Byte byWide;
}STRect;

  名为 STRect 的结构体拥有两个成员 byLenbyWide ,要对其访问可以通过一个成员运算符即可访问 stRect.byLenstRect.byWide
  如果成员多几个 类别 ,往往会进行二次封装,比如矩形有关于尺寸的成员变量,也有关于颜色的成员变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdint.h>

typedef uint8_t Byte;

typedef struct Rect
{
struct
{
Byte byLen;
Byte byWide;
}stSize; //结构体成员名。

struct
{
Byte byRed;
Byte byGreen;
Byte byBlue;
}stColor; //结构体成员名。
}STRect;

int main(void)
{
STRect stRect = {.stSize = {.byLen = 0u, .byWide = 0u},
.stColor = {.byRed = 0u, .byGreen = 0u, .byBlue = 0u}};

printf("%d, %d, %d, %d, %d\n", stRect.stSize.byLen, stRect.stSize.byWide,
stRect.stColor.byRed, stRect.stColor.byGreen, stRect.stColor.byBlue);
}

  随着封装的层级越多,访问时写出的表达式又长又难看,为了保证封装性的同时又方便变量调用,可以采用匿名结构体。

2 结构体嵌套匿名结构体

  匿名结构体没有结构体名,可以直接访问匿名结构体的成员。匿名结构体需要嵌套在具名结构体或联合内,直接定义无名结构体将无法进行访问,语法不允许也无意义。上面的结构体我们可以进行简化为以下定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdint.h>

typedef uint8_t Byte;

typedef struct Rect
{
struct
{
Byte byLen;
Byte byWide;
}; //匿名结构体。

struct
{
Byte byRed;
Byte byGreen;
Byte byBlue;
}; //匿名结构体。
}STRect;

int main(void)
{
STRect stRect = {.byLen = 0u, .byWide = 0u,
.byRed = 0u, .byGreen = 0u, .byBlue = 0u};

printf("%d, %d, %d, %d, %d\n", stRect.byLen, stRect.byWide,
stRect.byRed, stRect.byGreen, stRect.byBlue);
}

3 联合嵌套匿名结构体

  匿名结构体更常用于联合中,通过嵌套在联合中即加强的了数据的封装性,也是的对整体和局部数据的赋值和访问操作更方便。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdint.h>

typedef uint8_t Byte;
typedef uint32_t DWord;

typedef union Rgb
{
DWord dwVal;

struct
{
Byte byRed;
Byte byGreen;
Byte byBlue;
}; //联合内需要注意大小端。
}URgb;

int main(void)
{
URgb uRgb = {.dwVal = 0x00A5A5A5};

printf("%d, %d, %d", uRgb.byRed, uRgb.byGreen, uRgb.byBlue);
}