1:简单理解,结构体就是数组的进一步发展,数据的优点和缺陷在于数据里面是元素类型必须相同,但是结构体没有这个要求,结构体里面元素的类型可以相同也可以不同。
2:结构体的定义:
struct student
{
int age;
char name[20];
}s1;
上面这种方法是结构体定义的同时定义变量,结构体的定义有两部分组成
struct studen:结构体的类型
s1:类型为struct student的结构体变量,当然还可以用struct studet s2;l来定义变量s2
注意结构体里面的元素不能再创建的时候直接赋值,而是要通过外部访问来对结构体进行填充
3:结构体里面变量的访问
结构体里面的元素访问方式有两种,一种是 . 一种是->,但其实质上都是通过指针来访问的。
C语言规定用结构体的变量来访问结构体的时候是用 . 用结构体变量的指针来访问结构体的时候用->
4:结构体的对齐访问
首先要知道一点,我们使用 . 的方式来访问结构体时是不同考虑结构体内存对齐问题的,这部分编译器会帮我们处理,但是如果我们想通过指针方式来访问结构体里面的各元素的时候就需要考虑内存对齐的问题。结构体内存对齐访问一个主要原因是硬件本身的物理限制,使用对齐访问可以提高访问的效率。但是内存对齐也会带来内存空间浪费的问题,所以内存对齐访问实际上是通过牺牲内存空间来换取的速度。
5:结构体对齐的规则和运算
编译器本身可以设置内存对齐的规则,但是一下几点规则需要记住
(1)32位编译器,一般米、默认是4字节对齐
(2)结构体整体本身必须安置在4字节对齐处,也就是结构体的首地址必须是4整数的倍数(如果编译设置为n字节对齐访问,则首地址就是n的整数倍(n = 1 2 4 8 16 ...))
(3)结构体中每个元素本身必须对齐存放
(4)整个结构体的所占的内存空间必须是4的整数倍(同样如果是n字节对齐就是n的整数倍)
struct mystruct1
{ //1字节对齐 //4字节对齐
int a; // 4 // 4
char b; //1 // 2
short c; //2 // 2
}mystr1;
struct mystruct2
{ //1字节对齐 //4字节对齐
char a; // 1 // 4 (1+3)3字节填充
int b; //4 // 4
short c; //2 // 4 (2 +2)2字节填充
}mystr2;
分析:
首先是整个结构体,整个结构体变量4字节对齐是由编译器保证的,然后再是第一个元素a,a的开始抵制就是整个结构体的开始地址,所以自然就是4字节对齐的,但是的结束地址此时是不确定的,得由下一个元素决定;
第二个元素b,因为上一个元素a本身占4字节,其本身就是对齐的,所以留给b的开始地址也是4字节对齐,所以b就可直接存放(b存放的开始位置就决定a要占多少个字节,这里因为元素a字节刚好满足4字节对齐,不需要进行填充,所以这里a就占4字节),b的起始地址决定后,结束地址的确定需要依赖于下一个元素,原因是可能要进行填充,并且下一个元素的类型不通,则需要填充的字节数也是不同的;