• 【C进阶】之结构体嵌套及对齐


    嵌套结构体

    1. 格式:
      typedef struct 结构体名 {
      struct 结构体名1 结构体变量名1;
      struct 结构体名2 *结构体指针变量名1;
      }结构体别名_t;

    2. 定义结构体普通的变量,访问结构体中的成员:
      结构体别名_t 普通结构体变量名;

      普通结构体变量名.结构体变量名1.成员名;
      普通结构体变量名.结构体指针变量名1->成员名;

    3. 定义结构体指针变量,访问结构体中的成员
      结构体别名_t *结构体指针变量名;

      结构体指针变量名->结构体变量名1.成员名;
      结构体指针变量名->结构体指针变量名1->成员名;

    总结,访问结构体中的成员时,具体使用.还是->,需要看当前的结构体变量的类型。

    测试用例:

    #include 
    #include 
    #include 
    
    typedef struct Person
    {
        char *name;
        int age;
        char sex;
    } Person_t;
    
    typedef struct Student
    {
        Person_t per;
        int score;
    } Student_t;
    
    typedef struct Teacher
    {
        Person_t *per_p;
        int salary;
    } Teacher_t;
    
    int main(int argc, const char *argv[])
    {
        /*your code*/
        // 1. 定义结构体类型的变量
        Student_t stu1;
        // 2. 初始化结构体中的成员
        stu1.per.name = (char *)malloc(sizeof(char) * 20);
        if (stu1.per.name == NULL)
        {
            printf("malloc failed\n");
            return -1;
        }
        strcpy(stu1.per.name, "zhoukai");
        stu1.per.age = 18;
        stu1.per.sex = 'M';
        stu1.score = 99;
        printf("姓名:%s 年龄:%d 性别:%c 工资:%d\n",\
            stu1.per.name, stu1.per.age, stu1.per.sex, stu1.score);
    
        // 使用Teacher_t定义结构体指针类型的变量,使用malloc分配空间
        Teacher_t *t=(Teacher_t *)malloc(sizeof(Teacher_t));
        if(NULL==t)printf("malloc memory filed!\n");
        // 对Teacher_t类型中的per_p成员,使用malloc分配空间,
        t->per_p =(Person_t *)malloc(sizeof(Person_t));
        if(NULL==t->per_p)
        {
            printf("malloc memory filed!\n");
            return -1;
        }
        // 对Person_t中的name成员,使用malloc分配空间。
        t->per_p->name=(char *)malloc(sizeof(char)*20);
        if(NULL==t->per_p->name)
        {
            printf("malloc memory filed!\n");
            return -1;
        }
        // 分配堆区空间时,从外向内进行分配;释放空间时,从内向外分配空间。
    
        strcpy(t->per_p->name,"yao");
        t->per_p->age=10;
        t->per_p->sex='M';
        t->salary=100000;
        
        printf("姓名:%s 年龄:%d 性别:%c 工资:%d\n",\
            t->per_p->name,t->per_p->age, t->per_p->sex,t->salary);
    
        //释放空间
        free(t->per_p->name);
        t->per_p->name=NULL;
        free(t->per_p);
        t->per_p=NULL;
        free(t);
        t=NULL;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    图解:
    在这里插入图片描述

    结构体内存对齐

    32位的操作系统

    1. 结构体中成员内存对齐,只考虑基本的数据类型,不考虑构造类型,构造类型最终也是由基本类型构成。
      1> 如果结构体中的成员最大的成员只占1个字节的空间,则结构体类型的大小为1的整数倍;
      2> 如果结构体中的成员最大的成员只占2个字节的空间,则结构体类型的大小为2的整数倍;
      3> 如果结构体中的成员最大的成员只占4/8个字节的空间,则结构体类型的大小为4的整数倍;

    结构体中的成员的地址:
    1> 如果结构体中的成员为char类型,此成员的地址是1的整数倍;
    2> 如果结构体中的成员为short类型,此成员的地址是2的整数倍;
    3> 如果结构体中的成员为int,long int, long long int, float, double 类型,
    此成员的地址是4的整数倍;

    编译成32位的可执行程序:
    gcc ***.c -m32

    测试:

    #include 
    #include 
    #include 
    
    //1> 如果结构体中的成员最大的成员只占1个字节的空间,则结构体类型的大小为1的整数倍;
    typedef struct{
        char name[20];
        char sex;
        char age;
    }A_t;
    
    //2> 如果结构体中的成员最大的成员只占2个字节的空间,则结构体类型的大小为2的整数倍;
    typedef struct{
        char name[20];
        short age;
        char sex;
                // 保留一个字节
    }B_t;
    typedef struct{
        char name[20];
        char sex;
                // 保留一个字节
        short age;
    }C_t;
    
    //3> 如果结构体中的成员最大的成员只占4/8个字节的空间,则结构体类型的大小为4的整数倍;
    typedef struct{
        char name[20];
        char sex;
                // 保留三个字节
        int age;
    }D_t;
    
    typedef struct{
        char name[20];
        char sex;
                // 保留一个字节
        short score;
        int age;
    }E_t;
    
    typedef struct{
        char name[20];
        char sex;
                // 保留一个字节
        short score;
        long long int age;
    }F_t;
    typedef struct{
        char *name;
        char sex;   
                // 保留一个字节
        short score;
        long long int age;
    }G_t;
    typedef struct{
        char *name;
        char sex;   
                // 保留一个字节(不同类型的在同一行,不同的那个从后往前补!!!)
        short score;
        char salary; 
        long long int age;
    }H_t;
    
    int main(int argc, const char *argv[])
    {
        /*your code*/
        printf("A_t type size=%d\n",sizeof(A_t));//22
        printf("B_t type size=%d\n",sizeof(B_t));//24
        printf("C_t type size=%d\n",sizeof(C_t));//24
        printf("D_t type size=%d\n",sizeof(D_t));//28
        printf("E_t type size=%d\n",sizeof(E_t));//28
        printf("F_t type size=%d\n",sizeof(F_t));//32
        printf("G_t type size=%d\n",sizeof(G_t));//16
        printf("H_t type size=%d\n",sizeof(H_t));//20
    
        printf("-----------G_t中成员的地址-----------\n");
        G_t g;
        printf("G_t成员 char *name 的地址%p\n",g.name);
        printf("G_t成员 char sex 的地址%p\n",&g.sex);
        printf("G_t成员 short score 的地址%p\n",&g.score);
        printf("G_t成员 long long int age 的地址%p\n",&g.age);
    
        printf("-----------H_t中成员的地址-----------\n");
        H_t h;
        printf("H_t成员 char *name 的地址%p\n",h.name);
        printf("H_t成员 char sex 的地址%p\n",&h.sex);
        printf("H_t成员 short score 的地址%p\n",&h.score);
        printf("H_t成员 char salary 的地址%p\n",&h.salary);
        printf("H_t成员 long long int age 的地址%p\n",&h.age);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    64位的操作系统

    1. 结构体中成员内存对齐,只考虑基本的数据类型,不考虑构造类型,构造类型最终也是由基本类型构成。
      1> 如果结构体中的成员最大的成员只占1个字节的空间,则结构体类型的大小为1的整数倍;
      2> 如果结构体中的成员最大的成员只占2个字节的空间,则结构体类型的大小为2的整数倍;
      3> 如果结构体中的成员最大的成员只占4个字节的空间,则结构体类型的大小为4的整数倍;
      4> 如果结构体中的成员最大的成员只占8个字节的空间,则结构体类型的大小为8的整数倍;

    结构体中的成员的地址:
    1> 如果结构体中的成员为char类型,此成员的地址是1的整数倍;
    2> 如果结构体中的成员为short类型,此成员的地址是2的整数倍;
    3> 如果结构体中的成员为int,float类型,
    此成员的地址是4的整数倍;
    4> 如果结构体中的成员为long int, long long int, double 类型,
    此成员的地址是8的整数倍;
    编译成64位的可执行程序:
    8的整数倍;

    结构体中的成员的地址:
    1> 如果结构体中的成员为char类型,此成员的地址是1的整数倍;
    2> 如果结构体中的成员为short类型,此成员的地址是2的整数倍;
    3> 如果结构体中的成员为int,float类型,
    此成员的地址是4的整数倍;
    4> 如果结构体中的成员为long int, long long int, double 类型,
    此成员的地址是8的整数倍;
    编译成64位的可执行程序:
    gcc ***.c

  • 相关阅读:
    数字政府一网统管体系下的运维管理软件应用探讨
    3.81 OrCAD软件绘制原理图时如何使用任意角度的走线?OrCAD软件怎么统一查看哪些元器件是没有PCB封装的?
    vue+element项目创建步骤
    chrome 浏览器 f12 如何查看 websocket 消息?
    Java----内部类、外部类、匿名对象、匿名对象的创建
    OpenGL入门(五)之Matrix矩阵操作和坐标系统
    Python3中的“加和”函数
    snowflake 不再是个数据仓库公司了
    基于文件上传漏洞获得网站 shell 权限
    常见8种数据结构
  • 原文地址:https://blog.csdn.net/distant_Rove666/article/details/127782096