第18讲:⾃定义类型:结构体

目录

  1. 结构体类型的声明
  2. 结构体内存对⻬
  3. 结构体传参
  4. 结构体实现位段

1.结构体类型的声明

1.1 结构体回顾

(1)结构体的声明

注:分号不能丢。

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

注:结构体变量 . 成员名 == 结构体指针 -> 成员名。

(3)结构体类型的重命名

这样后面创建变量 x,可以直接写成 S x。

1.2 结构体的特殊声明

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

(1)匿名结构体类型

匿名结构体类型只能使用一次,后续不能使用这个类型再创建变量。

比如:

此时若写出代码 ps = &x 会报错,因为在编译器看来,这两个匿名结构体类型并不相同,故也可反应出匿名结构体类型只可以使用一次。

1.3 结构体的⾃引⽤

(1)错误方法:

⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的⼤⼩就会⽆穷的⼤,是不合理的。

(2)正确写法:

地址的大小是固定的。

(3)结构体自引用时重命名时要注意一些问题:

  • 正确写法:

  • 错误写法1:

  • 错误写法2:

2.结构体内存对齐

2.1 对齐规则

(1)结构体的第1个成员对⻬到和结构体变量起始位置偏移量为0的地址处。
注:偏移量为0是指针指向的位置,就是结构体变量本身的起始位置,没有向后偏移。

(2)从第2个成员变量开始,都要对⻬到某个对⻬数的整数倍的地址处(即找偏移量是对齐数的整数倍的地址处)。

  • 对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩中的较⼩值(VS 中默认的值是8)。

(3)结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。

(4) 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处。

(5)例:

该结构体大小为 8。

2.2 修改默认对齐数

#pragma 这个预处理指令,可以改变编译器的默认对⻬数。

对齐数设置的一般都是二的次方数。

3. 结构体传参

printf2 函数更好些,因为一个是传值调用,一个是传址调用,该 s 变量很大,而传值调用又要再创建一个变量(很大),效率很低。而传址调用传过去的是地址,只需要再创建一个指针变量,大小很小,效率更高。

总结:结构体传参的时候,要传结构体的地址。

4.结构体实现位段

4.1 什么是位段

位段的声明和结构是类似的,有两个不同:

(1)位段的成员必须是 int 、unsigned int 或 signed int ,在C99中位段成员的类型也可以选择其他整型家族类型,⽐如:char。

(2)位段的成员名后边有⼀个冒号和⼀个数字。

(3)例子:

注:数字表示这个成员要占用的比特位的数量。

4.2 位段的内存分配

(1)位段的成员可以是 int 、unsigned int 、signed int 或者是 char 等类型。

(2) 位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的。

注:位段的好处是可以节省空间。

4.3 位段使⽤的注意事项

如果位段的⼏个成员共用同⼀个字节,这样有些成员是没有地址的,因为只有每个字节才有地址。所以不能对位段的成员使⽤&操作符。

相关推荐
滕州市燕猫虎计算机科技工作室个体工商户9 小时前
《Rust程序设计》学习笔记八:结构体
笔记·学习·rust·rust程序设计
志尊宝10 小时前
Vue3 零基础每日笔记(082):文件上传实战——el-upload 校验、自定义上传、头像预览
前端·javascript·vue.js·笔记·#javascript·#vue.js
后季暖11 小时前
电商问数笔记(2)
笔记
xier_ran11 小时前
【infra之路】AI 编译器学习笔记(二):重拾 C++——移动语义与 LLVM 风格的类型转换
人工智能·笔记·学习
wuyk55513 小时前
嵌入式驱动开发:量产级工程化实战(第9篇)——低功耗下的通信可靠性
c语言·驱动开发·stm32·单片机·嵌入式硬件
星恒随风14 小时前
Linux库的底层原理:ELF文件格式、静态链接、程序加载、虚拟地址空间与GOT/PLT详解
linux·运维·笔记·学习·状态模式
罗西的思考14 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 — (7)— 混合机制
笔记·学习
学逆向的14 小时前
C 突破编译器限制
c语言·开发语言·网络安全
ClinicTech15 小时前
婴儿培养箱技术笔记:温控、报警与数据记录的三层架构
笔记
xiaominngtongxue15 小时前
从一次接触网实训课看中职实训教学的组织逻辑
笔记