C语言 自定义类型:结构体 与 联合体

目录:

1、结构体类型的声明

2、结构体的变量的创建和初始化

3、结构体内存的对齐

4、结构体实现位段

一、 结构体的声明

在声明结构体的时候,可以不完全的声明

struct

{

int a;

char b;

float c;

}s;

struct

{

int a;

char b;

float c;

}* ps;

int main()

{

ps = &s;

//这种写法是有问题的,虽然上面两个匿名结构体类型成员一摸一样,

// 但是在编译器看来,是两个不同的类型

return 0;

}

二、结构体的自引用

struct Node

{

int data;

struct Node* next; // 👈 这就是自引用

};

重点:

必须用指针 struct Node,不能用 struct Node!

为什么要用自引用?(用来做链表!)

你可以把它理解成:

火车车厢

  • 每节车厢 = 一个结构体
  • 车厢里有一个 "钩子" = 指针
  • 钩子钩住下一节车厢

这就是链表 !结构体自引用 = 造链表的核心

结构体自引用 = 结构体内部包含一个指向自己的指针

作用:用来造链表、二叉树、图等复杂数据结构!

三、结构体内存对齐

结构体成员默认情况下不一定是连续存放的,由下面这段代码可以证明:

struct s1

{

char c1;

int i;

char c2;

};

struct s2

{

char c1;

char c2;

int i;

};

int main()

{

printf("%zu\n", sizeof(struct s1));

printf("%zu\n", sizeof(struct s2));

return 0;

}

为什么要对齐?

为了让 CPU读得更快 。结构体不是挨个紧挨着存的,而是按规则排队、有空位

结构体对齐规则

1. 第一个成员 从偏移 0 开始

2. 从第二个成员开始

对齐到 它自己大小 的整数倍地址

  • char (1) → 对齐到 1 的倍数
  • int (4) → 对齐到 4 的倍数
  • double (8) → 对齐到 8 的倍数

3. 结构体总大小

必须是 最大成员类型大小 的整数倍

4. 如果有嵌套结构体

嵌套的内部成员对齐到 自己最大成员的大小

四、结构体的位段

位段类型:

:冒号 后面加上 数字 (这个数字表示这个成员需要占用多少个二进制位)

当剩余空间不够时,会新开一个单元

放不下就重新开一块空间,不跨单元存放

struct A

{

int _a : 2;

int _b : 5;

int _c : 10;

int _d : 30;

}; // 当你这么设计位段成员的时候,就意味着这些成员的长度足够自己使用

位段的内存分配

为什么要用位段?

省空间!

  • 正常 int 要 4 字节(32 位)
  • 但很多数据根本用不到那么多位比如:性别(0/1)、状态(0~7)

用位段可以把多个变量挤在同一个字节里

位段的特点(超级重要)

  1. 节省内存
  2. 不能取地址 & (原因:位段的几个成员共有同一个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的。内存中每个字节分配一个地址,一个字节内部的bit位是没有地址的,所以不能对位段成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在一个变量中,然后赋值给位段的成员)
  3. 不能跨平台,移植性差
  4. 不能用数组
  5. 主要用于协议、硬件寄存器、网络包等对空间要求极高的地方

位段分配内存的规则

  1. 位段是按 "位" 分配,不是按字节
  2. 先从低位往高位填(从右往左填)
  3. 当前单元剩下的位不够放 → 浪费掉,新开一个单元
  4. 单元大小由 "位段的类型" 决定
    • int 型位段 → 单元 = 4 字节(32 位)
    • char 型位段 → 单元 = 1 字节(8 位)
相关推荐
jieyucx1 小时前
Go 语言 JSON 序列化与反序列化
开发语言·golang·json·序列化
罗超驿1 小时前
6.Java多线程详解:Thread类、线程属性与start()方法深度解析
java·开发语言·面试·java-ee
yzq1991271 小时前
10.C语言-表达式、左值与语句
c语言·指针·函数·表达式·语句
海的透彻1 小时前
jmeter预制处理器JSR223-加解密
开发语言·jmeter·sm2·jsr233
asyxchenchong8881 小时前
R+VIC 模型融合实践技术应用及未来气候变化模型预测
开发语言·r语言
Run_Teenage1 小时前
算法模板:输入输出,并查集
java·开发语言·算法
chengO_o2 小时前
AVL树详解与实现(C++)
数据结构·c++·avl树·平衡二叉搜索树
玉树临风ives2 小时前
atcoder ABC 458 题解
数据结构·c++·算法
古城小栈2 小时前
Rust Tauri:构建轻量高性能跨平台桌面应用
开发语言·后端·rust