成员指针、柔性数组、联合、大小端系统的优缺点以及使用

结构的成员指针:
    当结构的某一项成员数量不固定,我们可以使用指针数据+指针+堆内存,根据实际情况存储成员,例如不同年级的学生成绩数量是不确定的。

内存申请的方式举例如下:


    typedef struct Student
    {
        int id;
        char name[20];
        int score_cnt;
        float* score;
    }Student;

    // 定义成员,使用栈内存
    Student stu = {1001,"hehe",2};
    stu.score = malloc(sizeof(*stu.score)*stu.score_cnt);
    free(stu.score);

    // 定义成员,使用堆内存
    Student* stup = malloc(sizeof(Student));
    stup->score = malloc(sizeof(*stup->score)*stup->score_cnt);

内存的释放:

    free(stup->score);
    free(stup);

注意:不管结构变量如果定义的,必须给成员指针单独分配堆内存,否则成员指针就是野指针,在结构变量使用完毕后还必须单独释放,否则就会产生内存泄漏。

柔性数组:
    当结构的某一项成员数量不固定,我可以在结构的末尾定义一个长度为零的数组,这种数组就叫柔性数组,在为结构变量分配内存时多分配一些,多分配的内存就归柔性数组使用。

使用举例:

 typedef struct Student
    {
        int id;
        char name[20];
        int score_cnt;
        float score[]; // 柔性数组
    }Student;

    Student* stup = malloc(sizeof(Student)+sizeof(stup->score[0])*len);
    stup->score = len;

    for(int i=0; i<stup->score_cnt; i++)
    {
        scanf("%f",&stup->score[i]);1
    }

    free(stup)

使用成员指针的缺点:
        1、使用麻烦,必须两次分配,两次释放。
        2、危险性高,容易出现野指针、内存泄漏。
        3、结构变量和成员指针所指向的内存是两个独立的内存块,容易产生内存碎片。
        4、成员指针会占用结构的4|8字节空间,再考虑对齐和补齐,浪费的内存更多。

    柔性数组的优点:
        1、使用方便,不需要单独为柔性数组分配内存,只需要为结构变量分配内存时多分配一些即可。
        2、安全性高,柔性数组只是结构中的标记符,因此不会使用到野指针。
        3、柔性数组所使用内存块与结构变量是一体的,与结构变量的内存一起分配一起释放,因此也不容易产生内存泄漏、内存碎片。
        4、节约内存,柔性数组只是结构中的标记符,不会占用结构额外的内存。

    柔性数组的缺点:
        这种语法在是C99语法标准中提出并实现的,早期的只支持C89的编译器,不支持此用法,通用性不强。

 联合:
    联合的使用语法与结构一模一样,联合与结构的区别,联合的所有成员共用一块内存。

union 联合名
    {
        成员类型 成员名;
        ...
    };

    union Data
    {
        char ch;
        int num;
        long ld;
        int* p;
    };

    union Data d;

 使用联合的意义:
        使用少量内存对应若干个标识符,只要他们不同时使用,就不会冲突,能大大节约内存,还可以对一内存进行不同格式的解释

 联合的总字节数:
        由于所有成员共用一块内存,所以成员天然对齐的,但要考虑补齐。

举例:

        union Data
        {
            char arr[5];
            int num;
        };
        sizeof(union Data); // 结果是8

大端系统与小端系统:
    假定int类型变量,它的4个字节存储内存地址分别是:
        0xbff97558 低地址
        0xbff97559
        0xbff9755a
        0xbff9755b 高位地址
    假如有一个十六进制整数:0xa1b2c3d4
        0xa1 高位数据
        0xb2
        0xc3
        0xd4 低位数据

    大端系统:低位数据存储在高位地址,大型服务器、网络设置采用的是大端系统,所以大端格式也叫网络字节序。
        0xbff97558 存储0xa1
        0xbff97559 存储0xb2
        0xbff9755a 存储0xc3
        0xbff9755b 存储0xd4

    小端系统:低位数据存储在低位地址,一般个人计算机都采用小端系统。
        0xbff97558 存储0xd4
        0xbff97559 存储0xc3
        0xbff9755a 存储0xb2
        0xbff9755b 存储0xa1

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值