• C杂讲 结构体对齐


    目录

    知识点1 【结构体对齐问题】

    知识点2【 结构体嵌套结构体】

     知识点3【 强制内存对齐】

     知识点4【 拓展求结构体成员的偏移量】


    知识点1 【结构体对齐问题】

    1、知识点的引入:

    1. struct data1
    2. {
    3.     char a;//1B
    4.     int b;//4B
    5. };
    6. void test01()
    7. {
    8.     printf("%d\n",sizeof(struct data1));//8B 为啥?
    9. }

    2、对齐规则(默认对齐)

    第一步:确定分配单位(每行开辟多少字节)

                    结构体中最大的基本类型的长度 为分配单位。

    第二步:确定成员的偏移位置

                    偏移位置:成员自身类型的整数倍(0~n倍)

    第三步:收尾工作:

                    结构体的总大小必须是分配单位整数倍

    1. struct data
    2. {
    3. char c;//1B
    4. int i;//4B
    5. };
    6. void test05()
    7. {
    8. struct data d;
    9. //结构体的大小 >= 成员大小之和
    10. printf("%d\n",sizeof(struct data));//8
    11. printf("&d.c = %u\n",&d.c );
    12. printf("&d.i = %u\n",&d.i );
    13. }

    运行结果:

    案例:

    1. typedef struct
    2. {
    3. int a;
    4. char b;
    5. short c;
    6. char d;
    7. }DATA;
    8. void test06()
    9. {
    10. DATA d;
    11. printf("%d\n", sizeof(DATA));
    12. printf("%u\n", &d.a);
    13. printf("%u\n", &d.b);
    14. printf("%u\n", &d.c);
    15. printf("%u\n", &d.d);
    16. }

    案例1:

    1. struct data1
    2. {
    3.     char a;//1B
    4.     int b;//4B
    5. };

     案例2:

    1. struct data2
    2. {
    3. char a;
    4. short b;
    5. char c;
    6. int d;
    7. };

     案例3:

    1. struct data2
    2. {
    3. char a;
    4. short b;
    5. short c;
    6. char d;
    7. };

     案例4:

    1. struct data2
    2. {
    3. char a[7];
    4. short b;
    5. int c;
    6. };

    知识点2【 结构体嵌套结构体】

    第一步:确定分配单位(每行开辟多少字节)

                    所有结构体中最大的基本类型的长度 为分配单位。

    第二步:确定成员的偏移位置

                    普通成员偏移位置:成员自身类型的整数倍(0~n倍)

                    结构体成员的偏移量:该结构体的最大基本类型的整数倍

    第三步:收尾工作:

                    结构体成员:是该结构体的最大基本类型整数倍

                    结构体的总大小必须是分配单位的整数倍

     

     案例:

    1. typedef struct
    2. {
    3. short d;
    4. char e;
    5. }DATA2;
    6. typedef struct
    7. {
    8. short a;
    9. int b;
    10. DATA2 c;
    11. char f;
    12. }DATA;
    13. void test08()
    14. {
    15. DATA data;
    16. printf("%d\n",sizeof(DATA));
    17. printf("a:%u\n", &data.a);
    18. printf("b:%u\n", &data.b);
    19. printf("c中d:%u\n",&data.c.d);
    20. printf("c中e:%u\n",&data.c.e);
    21. printf("f:%u\n",&data.f);
    22. }

     案例:

    1. typedef struct
    2. {
    3. char a;
    4. int b;
    5. short c;
    6. }DATA;
    7. void test10()
    8. {
    9. DATA data={'a',100, 20};
    10. char *p = &data;
    11. printf("c = %hd\n", data.c);
    12. //需求 借助p访问20
    13. printf("c = %hd\n", *(short *)(p+8));
    14. }

     运行结果:

    案例:

    1. struct A
    2. {
    3.     char b;
    4.     short c;
    5. };
    6. struct B
    7. {
    8.     int a;
    9.     struct A ob;//结构体成员的偏移量
    10. int d;
    11. };

     案例1:

    1. struct A
    2. {
    3.     short b;
    4.     char c;
    5. };
    6. struct B
    7. {
    8. int f;
    9.     char a;
    10.     struct A ob;//结构体成员的偏移量
    11. char d;
    12. };

     知识点3【 强制内存对齐】

    #pragma pack (value)时的指定对齐值value

    第一步:确定分配单位(每行开辟多少字节)

                    min(value,最大的基本类型的长度) 为分配单位。

    第二步:确定成员的偏移位置。

                    偏移位置:成员自身类型的整数倍(0~n倍)

    第三步:收尾工作:

                    结构体的总大小必须是分配单位整数

    1. #include <stdio.h>
    2. #include<stdio.h>
    3. #pragma pack (4)
    4. struct stu
    5. {
    6.     char a;
    7.     short b;
    8.     short c;
    9. };
    10. void test01()
    11. {
    12.     printf("%d\n",sizeof(struct stu));//6
    13. }

    注意事项:

     知识点4【 拓展求结构体成员的偏移量】

    1. struct stu1
    2. {
    3.     char a;
    4.     int b;
    5.     char c;
    6.     int d;
    7. };

    1. #include <stdio.h>
    2. #include<stdio.h>
    3. struct stu1
    4. {
    5.     char a;
    6.     int b;
    7.     char c;
    8.     int d;
    9. };
    10. #define  OFF_SET(TYPE, member) (int)&(((TYPE *)0)->member)
    11. void test01()
    12. {
    13.     struct stu1 data;
    14.     printf("偏移量:%d\n",   OFF_SET(struct stu1, b) );//8
    15.     
    16. }
  • 相关阅读:
    15.操作系统死锁处理
    [Vue]大屏界面自适应-transform: scale() translate(x, y)
    利用cms主题构造木马(CVE-2022-26965)
    C++ std::make_unique和std::make_shared用法
    22-数据结构-内部排序-选择排序
    人生中第一次向开源项目提交PR记录
    『手撕Vue-CLI』自动安装依赖
    简述加密、摘要、数字签名、数字证书
    CentOS 7 下 SVN + Apache 对接 LDAP 服务
    队列【Java】
  • 原文地址:https://blog.csdn.net/qq_34981463/article/details/124936496