
good
文章目录
回顾结构体
(1)声明与创建
cpp
struct Stu
{
int age;
char name[20];
}s1;//第一种方式
struct Stu s2 = {12, "liming" };//第2种方式
(2)初始化
1,一般结构体
cpp
struct Stu
{
int age;
char name[20];
}s1={ 14, "lisi"};//第一种方式
struct Stu s2 = {12, "liming" };//第2种方式
struct Stu s2 = {.name="zhangsan", .age=19 };//第3种方式:指定顺序
2.嵌套结构体和结构体数组
cpp
struct Score
{
int math;
int chinese;
}
struct Stu
{
int age;
char name[20];
struct Score;
};
struct Stu n1={18,"lcj", {150,150}};
struct Stu n[2]={ {18,"lcj", {150,150}} ,{16,"ch",{140,149}} };
(3)对应的操作符
1.点:结构体变量可以用
2.箭头:结构体指针可以用
(4)结构体传参
- 尽量传指针
结构体新知识
(1)匿名结构体
- 结构体声明的时候没有名字,只能通过前面说的第一种方式创建,也只能够实现一次创建
cpp
struct
{
int age;
char name[20];
}s;
(2)结构体如何包含同种结构体
- 不能通过直接包含同种结构体的方式
- 应该包含同种结构体的指针
(3)结构体的对齐规则
- 作用:提高内存访问效率,减少CPU访问内存的次数。
-
官方解释

-
我的理解:( 8是默认对齐数,'min(8字节,成员的字节大小)' 称为 每个成员的对齐数)
- 存放内存从0开始算,大小是字节,总内存(字节大小)是数字+1
- 第一个结构体成员放到0,后面的成员都要放到" 自己的对齐数 的倍数"的位置
- 比如,(第一个以外)int a只能存放在4,8,12这些位置
- 总大小必须为最大对齐数的倍数
- 比如,结构体中有char ,int,short,那么总大小必须是4字节的倍数
-
具体实例
- int n从0到3,char a从4到5,
- 最大对齐数是4,结构体总长度是4的倍数,因为要大于5,所以是8
(4)修改默认对齐数
- #pragma pack(n) ------设置默认对⻬数为n
- 示例:
- char a从0到1,
- int n的对齐数是min(2字节,成员的字节大小)=2,所以int n从2到5
- 结构体总长度是2的倍数,所以是6
(5)结构体实现位段
1.是什么
- 为了节省空间,结构体的一种特殊的创建方式
- 能够修改结构体成员内存中占几个比特
2.条件
- 只有int, unsigned int,signed int 和char可以实现
- 想设置的比特数 得小于原比特数
- 比如int4字节,32bit,设置的位段得小于32
3.形式
-
创建结构体的时候,成员后面加上冒号和想设置的字节数
-
示例:
cpp#include<stdio.h> struct S { char a : 3; char b : 3; char c : 5; char d : 6; }; int main() { struct S s; s.a = 11; s.b = 5; s.c = 10; s.d = 8; printf("%zu\n", sizeof(s));//得到的结果是3 return 0; }
4.实现
- vs中的实现:
- 逐个字节(8bit)来分
- 从一个字节的从右向左来放成员
- 给同一个成员分配的bit都在同一字节
- 示例:
- 先分配1个字节00000000(8个bit)
- 然后从右往左给a 3个bit,因为a的2进制是1011,只能放后3个
- 放a后:00000011
- 再从右向左给b 3 个bit,b的二进制为101,都放进去
- 放b后:00101011
- 内存:一个字节,8 bit,2个16进制位,0010变成2, 1011变成b
- 现在第一个字节只剩下2个bit,而c需要5个bit,不够,再分配一个字节
- 放c之前00101011 00000000
- 从右往左给c 5个bit,c的二进制为1010,都放进去
- 放c后:00101011 00001010
- 内存:前方有2b,后面第二个字节,8 bit,2个16进制位,0000还是0, 1010变成a
- 现在第二个字节只剩下3个bit,而d需要5个bit,不够,再分配一个字节
- 放d之前00101011 00001010 00000000
- 从右往左给s 6个bit,d的二进制为100,都放进去
- 放d后:00101011 00001010 00000100
- 内存:前方有2b 0a,后面第三个字节,8 bit,2个16进制位,0000还是0, 0100变成8
- 先分配1个字节00000000(8个bit)
5.缺点
- 不可移植
- 从左往右放 还是从右往左放不确定
- 大小端问题
- 不同编译器布局不同
- 不能取地址(地址是字节的编号,bit太小)
- 调试困难
- 不能传参,改变了类型的字节数,相当于改变了类型
- 还是会浪费空间
字节,8 bit,2个16进制位,0000还是0, 0100变成8