C语言复杂数据类型

来源:互联网 发布:字符串转json对象 js 编辑:程序博客网 时间:2024/06/13 15:57

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的内存存储状态如图所示,画的不好见谅啊,本来已经写好了一篇博客,奈何不见了,不见了,对于有强迫症的我来说只好再来一篇。

A

下面看B的内存存储状态图

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;
0 0
原创粉丝点击