结构体与联合

翻译整理自 cppreference - 结构体。

1. 结构体定义

struct Point {
    int x;
    int y;
};

struct Point p = {1, 2};
struct Point q = {.x = 5, .y = 6};   // 指定初始化(C99)

使用 typedef 简化:

typedef struct {
    int x, y;
} Point;

Point p = {1, 2};

2. 成员访问

struct Point p = {1, 2};
p.x = 10;
p.y = 20;

struct Point *pp = &p;
pp->x = 100;        // 等价 (*pp).x

3. 嵌套结构体

struct Line {
    struct Point start;
    struct Point end;
};

struct Line l = { {0,0}, {3,4} };
l.start.x = 1;

4. 位域 Bit-field

struct Flags {
    unsigned int a : 1;     // 1 bit
    unsigned int b : 3;     // 3 bits
    unsigned int c : 4;
};

struct Flags f = {1, 5, 10};

位域布局依赖实现,跨平台需谨慎。

5. 结构体数组

struct Point pts[3] = { {1,1}, {2,2}, {3,3} };

for (int i = 0; i < 3; i++)
    printf("%d,%d\n", pts[i].x, pts[i].y);

6. 结构体与函数

值传递(拷贝开销大)

void print(struct Point p) {
    printf("%d,%d\n", p.x, p.y);
}

指针传递(推荐)

void move(struct Point *p, int dx, int dy) {
    p->x += dx;
    p->y += dy;
}

返回结构体

struct Point make(int x, int y) {
    struct Point p = {x, y};
    return p;
}

7. 动态分配

struct Point *p = malloc(sizeof(struct Point));
p->x = 1; p->y = 2;
free(p);

结构体数组:

struct Point *arr = malloc(10 * sizeof(struct Point));
arr[0].x = 1;
free(arr);

8. 联合 union

联合中所有成员共享同一块内存,写一个会覆盖其它:

union Value {
    int    i;
    double d;
    char   bytes[8];
};

union Value v;
v.i = 0x40490FDB;
printf("%f\n", v.d);     // 按不同方式解读同一字节

判断当前活跃成员需配合 enum:

struct Var {
    enum {IS_INT, IS_DOUBLE} type;
    union {
        int i;
        double d;
    } u;
};

9. 结构体内存对齐

struct A {
    char  c;     // 1 byte
    int   i;     // 4 byte,前补 3 byte
};              // sizeof = 8

可用 #pragma pack 改变对齐:

#pragma pack(push, 1)
struct A {
    char c;
    int  i;
};              // sizeof = 5
#pragma pack(pop)

<stdalign.h> / _Alignof:

printf("%zu\n", alignof(int));

10. 结构体与灵活数组成员

C99 起支持灵活数组成员:

struct Buffer {
    size_t size;
    char   data[];     // 大小 0
};

struct Buffer *b = malloc(sizeof(struct Buffer) + 100);
b->size = 100;

小结

结构体是 C 组织复杂数据的核心;联合与位域用于协议解析、内存紧凑场景。