---当你累到不行,还继续坚持,那就是梦想的力量
- 1.结构体类型的声明
- 2.结构体变量的创建和初始化
- 结构成员访问操作符
- 结构体内存对齐
- 结构体传参
1:结构体类型的声明
struct tag
{
member-list;
} variable-list;
如果说描述一个人的身份数据:
struct stu
{
char name[20];
int age;
float high;
char sex[5];
}
2:结构体变量的创建和初始化
1:
按结构体成员顺序初始化
2:
结构的特殊声明:
在声明结构的时候可以不完全声明
struct
{
int a;
char b;
float c;
}x;
结构在声明的时候,省略掉了结构体标签(tag) 所以,定义结构体的时候,最好不要使用匿名结构体。
3:
结构的自引用 :
如果一个结构体中包含同类型的成员是否可以呢?
struct node
{
int data;
struct node next;
};
我们仔细想一想,如果是这样,那这样结构体的变量大小是多少呢?无穷大?所以是不合理的。
正确的自引方式为:
struct node
{
int data;
struct node * next;
};
3.结构体内存对齐
我们了解内存对齐才能知道怎么计算结构体的大小
1.对齐规则
1.结构体的第一个成员对齐到和结构体变量起始位置偏移量为零的地址处
2.其他成员变量要对齐到对齐数的整数倍地址
(对齐数:编译器默认的对齐数(VS的为8)与该成员变量大小相比的较小值)
3.结构体的总大小为结构体成员中的成员变量最大(所占字节最大)的一个的对齐数的整数倍
4.如果嵌套的结构体的情况,也就是结构体中有一个成员也是结构体,嵌套的结构体成员对齐到自己成员中最大的对齐数的整数倍处,而外面的结构体的整体大小,就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍
如果是在VS中,其实对齐数就是成员变量所占字节数(int: 4 ,char: 1 ,double :8 ,float : 4)与8相比的较小值
首先,c1对齐零,然后int i要对齐它的最小整数倍上面,最后是9个字节,不是最大对齐数(也就是int为4)的整数倍所以要一直加到12,为四的整数倍,则12是它的,结构体的大小。
为什么存在内存对齐?
平台原因:
不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常
性能原因:数据结构,(尤其是栈)应该尽可能的在自然边界上对齐,原因在于为了访问未对齐的内存处理器需要做两次内存访问,而对齐的内存访问仅需要一次访问
比如一个处理器,总是从内存中读取八个字节,则地址必须是八的倍数。如果我们能保证将所有double类型的数据的地址都对齐成八的倍数,那么就可以用一个内存操作来读,或者写值了,否则我们可能需要执行两次内存访问,因为对象可能被分在两个八字节内存块中
总的来说:结构体的内存对齐是拿空间换时间的做法
所以我们要让占空间小的成员尽量集中在一起,这样我们既能满足对齐,又能节省空间
:
修改默认对齐数
#pragma 这个预处理指令可以改变编译器的默认对齐数
在结构体对齐方式不合适的时候,我们可以更改默认对齐数
4.结构体传参
相比于func1,func2更好
因为函数传参的时候,参数是需要压栈的,会有时间和空间上的系统开销,如果传一个结构体的对象,结构体对象很大的时候,参数压栈的系统开销就会变大,会导致性能的下降
结论:结构体传参的时候要传结构体的地址
标签:步天,struct,自定义,int,成员,任我行,内存,对齐,结构 From: https://blog.csdn.net/2402_87310323/article/details/143984422