【笔记】C语言的结构体
前言
C语言的结构体学习笔记
定义结构体并使用结构体变量
结构体使用
struct
关键字定义,结构体末尾有;
定义结构体,类似于OOP编程的创建类(当然,C语言是没有对象这个概念的,只不过是这里方便理解)
结构体内部可以定义多个变量,类似于OOP编程中类的属性
结构体变量的地址,实际上就是首元素的地址
在C语言中一个结构体至少要有一个成员变量,在C++定义结构体时可以没有成员变量
先调用后初始化
初始化全部成员变量
A
:结构体名a
:结构体变量名
1 | struct A |
只初始化部分变量
- 没有被初始化的成员变量值为0
1 | struct A |
调用时直接初始化
初始化全部成员变量
1 | struct A |
只初始化部分成员变量
不指定成员变量名
- 不指定成员变量名时,会按照定义顺序进行初始化,且其他没有被初始化的成员变量值为0
1 | int main() |
指定成员变量名
- 如果指定成员变量名,就不考虑顺序
1 | int main() |
结构体在内存中存放的方式
结构体在内存中存储数据时,如果与最大成员变量不对齐,则会自动对齐,对齐时空出来的空间保持为空,且如果有其他小于空的空间的数据存放时,会自动放到空的空间(但是这个数据会右对齐)
由于结构体的成员变量在内存中存储时是按顺序的,所以我们应该手动优化代码实现最省空间的存储
如果结构体出现数组,则按照数组内的具体成员的类型作为对齐标准
以下是优化前的代码:
- 这一组成员变量中,最长的是4个字节的int类型a4,所以,应按照4字节为一个单位的存储
- 先存a1,占用1字节,再存a2,占用2字节,但是是右对齐,所以一共消耗了4字节空间
- 然后存a3,占用1字节,接下来想要存a4,但是不够4字节了,所以a3占用4字节
- 最后存a4,占用4字节
- 最终占用12字节
1 | struct A |
以下是优化后的代码:
- 这一组成员变量中,最长的是4个字节的int类型a4,所以,应按照4字节为一个单位的存储
- 现存b1,占用1字节,再存b2,占用1字节,向右对齐
- 然后存b3,占用2字节,与b1、b2总共占用4字节
- 最后存b4,占用4字节
- 最终占用8字节
1 | struct B |
以比特为单位存储成员变量
- 指定的bit数不能超过当前定义的数据类型的最大的内存占用空间
<num>
:以几个bit存储数据
1 | struct A |
结构体数组
先调用后初始化
初始化全部成员变量
指定数组数量
1 | struct A |
不指定数组数量
1 | struct A |
初始化部分成员变量
1 | struct A |
调用时直接初始化
初始化全部成员变量
指定数组数量
1 | struct A |
不指定数组数量
1 | struct A |
只初始化部分成员变量
不指定成员变量赋值
1 | struct A |
指定成员变量赋值
1 | struct A |
结构体嵌套
- 在嵌套结构体时,结构体是作为一个整体存在的,所以对齐时只遵循子级结构体,而不是父级结构体
- 例如以下的结构体占用了12字节内存
1 | struct A |
结构体变量的复制
- 结构体变量的赋值,其实就是内存的拷贝
1 | struct A a = {}; |
操作符
- 操作符实际上就是尖头函数
->
定义一个结构体
1 | struct P |
没有使用操作符之前的结构体赋值
1 | struct P p; |
使用操作符之后的结构体赋值
1 | strcpy(p->name, "张三"); |
结构体作为函数参数
传递结构体
1 | struct A |
传递结构体脂针
1 | struct A |