1、结构体
一、结构体的三种定义方式
方式一:
//结构体标准写法
struct Person
{
int age;
char * name;
};
struct Person personNomal={20,"girl"};
方式二:
struct Person
{
int age;
char * name;
} Myperson={20,"girl"};//定义结构体的同时,初始化一个Person 结构体
struct Person personNomal={20,"beautiful girl"};//定义新的Person 结构体
方式三:
struct
{
int age;
char * name;
} Myperson={20,"girl"};//定义结构体的同时,初始化一个Person 结构体
struct
{
int age;
char * name;
} PersonNomal={20,"beautiful girl"};//定义新的Person 结构体 这种方式每次都要重新写一遍结构体,最是繁杂
2、结构体内存剖析
struct A
{
int a;
int b;
double c;
};
printf("A的size大小是:%d\n",sizeof(A));
struct B
{
int a;
double c;
int b;
};
printf("B的size大小是:%d\n",sizeof(B));
/**
* A的size大小是:16
B的size大小是:24
*
* */
结构体A的内存存储状态如图所示,画的不好见谅啊,本来已经写好了一篇博客,奈何不见了,不见了,对于有强迫症的我来说只好再来一篇。
下面看B的内存存储状态图
为什么会这样呢?
首先 成员 a在内存中 占4个字节,b占4个字节,c占8个字节
结构体中成员的内存的分配需要考虑到地址对齐的因素,A结构体中,由于c需要占用8个字节,所以分配的每个成员的最大长度是8
当a储存时首先占用了4个字节,b存也需要4个字节,而a正好剩余4个,所以a和b共同占用8个字节,c单独使用8个字节。
同理 当储存B结构体时,最大成员长度也是8,先分配出8个字节长度,成员a放进去了,剩余4个字节长度,这个时候需要存储c,c需要8个字节长度,所以a剩余的空间放不进去了,所以c单独占一行,存储b时只能再开辟8个字节长度。
其实很简单,计算结构体所占的内存长度只要简单的构思一下就可以了。
这里还有另外一种方法,首先理解几个概念。
偏移量:结构体内部成员的地址相对于结构体起始地址的长度。
结构体的长度:等于结构体最后一个成员的偏移量加上最后一个成员的本身的大小。
但是需要满足两个条件:
1、成员的偏移量等于成员自身大小的整数倍。
2、结构体的长度是所有成员大小的整数倍。
按照上面的方法分析上面代码中的两个结构体:
A
成员a的偏移量是0(0是任何大小的整数倍),同时a满足上面两个条件,成员b的偏移量是4(成员a的偏移量加上a自身的大小),满足条件(偏移量4是成员b的大小的整数倍),成员c的偏移量是8(成员b的偏移量加上成员b自身的大小),8是成员c的的整数倍,所以A的长度是成员c的偏移量加上成员c自身大小8等于16,16又是所有成员的整数倍,满足条件。
B
成员a的偏移量是0,成员c的偏移量是4,4不是成员c自身大小8的整数倍,所以偏移量4补上4(补全算法),成员b的偏移量是16(成员c的偏移量加上自身大小等于16),16是成员b自身大小的整数倍满足条件,所以B结构体的大小是16+4等于20不满足条件二,取成员a,b,c最小公倍数等于24.
特别的是:
struct C
{
int a;
char b[10];
int c[20];
};
printf("C的size大小是:%d\n",sizeof(C));
//结果是96 a的大小4 ,b的大小 10,c的大小20乘以4等于80,
//需要的最小内存是94,但是94不是a的倍数,补全2,等于96
3、结构体数组
//结构体数组
struct Person
{
int age;
char * name;
};
struct Person p[3]={{0,"jim"},{0,"jim"},{0,"jim"}};
// p[0]={0,"jim"};这样是不可以滴
p[0].age=10;
4、结构体指针
struct Person
{
int age;
char * name;
};
//结构体指针
//跟平常定义指针的方式没啥区别吧?
struct Person * PersonPoint;
struct Person person={27,"girl"};
PersonPoint=&person;
//指针修改结构体内成员变量
PersonPoint->age=28;
5、结构体嵌套
//结构体嵌套定义
struct Birthday
{
int year;
double month;
double day;
};
struct Person{
int age;
char * name;
struct Birthday b;
};
struct Person jim={20,"jim",{1990,11.0,4.0}};
printf("%d",sizeof(jim));
//结果:32 结构体Birthday的大小24 加上 person前两个成员的大小8
6、枚举
//枚举
enum Season
{
spring,
summer,
autuom,
winter
};
enum Season sea=spring;