结构体
本文最后更新于101 天前,其中的信息可能已经过时,如有错误请发送邮件至 2641805259@qq.com

1. 结构体的概念

结构体(struct)用于将多个不同类型的成员组合成一个整体,以描述复杂数据实体。

示例:

struct Student {
    int id;
    char name[20];
    float score;
};

结构体本质上是“用户自定义的数据类型”。


2. 结构体定义与声明

2.1 结构体类型定义

struct Point {
    int x;
    int y;
};

2.2 声明结构体变量

struct Point p;

2.3 定义类型别名(推荐)

使用 typedef 简化书写:

typedef struct {
	// 结构体成员
    int x;
    int y;
} Point;

Point p;

3. 结构体的初始化

3.1 顺序初始化

struct Point p = {10, 20};

3.2 指定成员初始化(C99)

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

4. 结构体成员访问

4.1 普通变量通过 .

p.x = 5;
p.y = 8;

4.2 指针变量通过 ->

struct Point *pt = &p;
pt->x = 5;
pt->y = 8;

.-> 的关系:

(*pt).x 等价于 pt->x
(*pt).y 等价于 pt->y

5. 结构体与内存布局

结构体的大小由以下因素影响:

  • 成员顺序
  • 成员对齐要求
  • 编译器填充(padding)

示例:

struct A {
    char c; // 1个字节
    char d; // 1个字节
    int  i; // 4个字节
};

可能大小为 8 字节(取决于平台):

  • char 占 1 字节
  • 后面补 3 字节填充
  • int 占 4 字节

大小由:sizeof(struct A) 决定。


6. 结构体与指针

6.1 结构体指针

struct Student s;
struct Student *p = &s;

p->score = 99.5;

6.2 指向结构体成员的指针

int *ptr = &(p->id);

6.3 使用 malloc 动态创建结构体

struct Student *stu = malloc(sizeof(struct Student));
stu->id = 1;

释放:

free(stu);

7. 结构体作为函数参数

7.1 按值传递(会复制结构体)

void print(struct Point p);

适用于小结构体。

7.2 按指针传递(无复制,效率高)

void modify(struct Point *p);

8. 结构体嵌套

8.1 结构体作为成员

struct Date {
    int y, m, d;
}; // 结构体的声明和定义
 
struct Student {
    int id;
    struct Date birth;   // 结构体的调用
};

访问:

s.birth.y = 2000;

8.2 自引用结构体(链表核心)

必须使用指针:

struct Node {
    int data;
    struct Node *next;
};

9. 结构体数组

struct Point{
	int x;
	int y;
}

struct Point arr[3] = {
    {1,2},
    {3,4},
    {5,6}
};

访问:

arr[1].x = 10;

10. 位段(Bit-fields)

用于精确指定字段的位数:

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

常用于嵌入式与通信协议。


11. 结构体与 typedef 的常见组合模式

11.1 基本用法

typedef struct {
    int x;
    int y;
} Point;

11.2 命名结构体 + typedef

typedef struct Student {
    int id;
    int age;
} Student;

11.3 自引用链表常见形式

typedef struct Node {
    int data;
    struct Node *next;
} Node;

12. 结构体内存拷贝

结构体可以整体赋值:

struct Point p1 = {1,2};
struct Point p2 = p1;  // 整体拷贝

也可以使用 memcpy:memory copy

memcpy(&p2, &p1, sizeof(p1));

13. 结构体与对齐控制(可选进阶)

#pragma pack(1)
struct A {
    char c;
    int  i;
};
#pragma pack()

强制按 1 字节对齐,可用于通信协议或磁盘格式解析。

14. 枚举(enum)

枚举用于定义一组“有意义的整型常量”,使代码更可读。

14.1 基本定义

enum Color {
    RED,
    GREEN,
    BLUE
};

枚举值默认从 0 开始递增:

RED=0, GREEN=1, BLUE=2

14.2 指定枚举值

enum Status {
    OK = 200,
    NOT_FOUND = 404,
    ERROR = 500
};

14.3 typedef 简化

typedef enum {
    MON, TUE, WED, THU, FRI, SAT, SUN
} Weekday;

Weekday w = MON;

14.4 应用场景

  • 状态码
  • 有限状态机
  • 标志值集合
  • 选项类型定义

15. 联合体(union)

联合体用于多个成员 共享同一段内存

特点:

  • 所有成员起始地址相同
  • 联合体大小 = 最大成员大小
  • 每次只能有效使用其中“一个成员”

15.1 定义

union Data {
    int   i;
    float f;
    char  str[20];
};

15.2 共享内存示例

union Data d;

d.i = 100;
printf("%d\n", d.i);

// 再存 float,会覆盖同一块内存
d.f = 3.14;
printf("%f\n", d.f);

// 读 d.i 是未定义行为

15.3 应用场景

联合体用于高效处理多种可能类型的数据:

  1. 协议解析(例如一个字节拆为 bit 段)
  2. 数据类型重解释(类型 punning)
  3. 嵌入式设备映射寄存器
  4. 节省内存的结构体复用

15.4 联合体 + 结构体混用(常见)

typedef struct {
    int type;
    union {
        int i;
        float f;
        char s[20];
    } data;
} Variant;

可实现“可变类型结构体”。

评论

  1. 猪包
    Macintosh Safari
    4 周前
    2026-3-18 10:28:39

    ( ๑´•ω•) “(ㆆᴗㆆ)

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇