C语言结构体嵌套与对齐超详细讲解

 更新时间:2022年12月26日 15:40:58   作者:编程远泊  
这篇文章主要介绍了C语言结构体嵌套与对齐,C语言中结构体是一种构造类型,和数组、基本数据类型一样,可以定义指向该种类型的指针。结构体指针的定义类似其他基本数据类型的定义

嵌套结构体

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

定义结构体普通的变量,访问结构体中的成员:

结构体别名_t 普通结构体变量名;

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

定义结构体指针变量,访问结构体中的成员

结构体别名_t *结构体指针变量名;

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

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

测试用例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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;
}

图解:

结构体内存对齐

32位的操作系统

结构体中成员内存对齐,只考虑基本的数据类型,不考虑构造类型,构造类型最终也是由基本类型构成。
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
//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;
}

64位的操作系统

结构体中成员内存对齐,只考虑基本的数据类型,不考虑构造类型,构造类型最终也是由基本类型构成。
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

到此这篇关于C语言结构体嵌套与对齐超详细讲解的文章就介绍到这了,更多相关C语言结构体嵌套内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++普通函数指针与成员函数指针实例解析

    C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下
    2014-08-08
  • C/C++ Qt数据库SqlRelationalTable关联表详解

    C/C++ Qt数据库SqlRelationalTable关联表详解

    这篇文章主要介绍了QT中SqlRelationalTable关联表组件的使用,文中代码对我们的学习和工作具有一定价值,感兴趣的朋友可以了解一下
    2021-12-12
  • c++11多种格式时间转化为字符串的方法实现

    c++11多种格式时间转化为字符串的方法实现

    本文主要介绍了c++11多种格式时间转化为字符串的方法实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C语言基础知识点指针的使用

    C语言基础知识点指针的使用

    这篇文章主要介绍了C语言基础知识点指针的使用,下面文章将让我们掌握指针的概念和用法、指针与数组之间的关系、指针指向的指针、如何使用指针变量做函数参数等更多相关内容,需要的小伙伴可以参考一下
    2022-03-03
  • Atom安装配置C/C++详细教程

    Atom安装配置C/C++详细教程

    Atom (一款开源的代码编辑器)是github专门为程序员推出的一个跨平台文本编辑器。这篇文章主要介绍了Atom安装配置C/C++教程,需要的朋友可以参考下
    2020-05-05
  • 教你用C语言实现三子棋

    教你用C语言实现三子棋

    这篇文章主要为大家详细介绍了C语言实现简单三子棋程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C++中vector的用法实例解析

    C++中vector的用法实例解析

    这篇文章主要介绍了C++中vector的用法,详细描述了vector的各种常见的用法及注意事项,需要的朋友可以参考下
    2014-08-08
  • C++ OpenCV裁剪图片时发生报错的解决方式

    C++ OpenCV裁剪图片时发生报错的解决方式

    在图像处理中,我们经常根据需要截取图像中某一区域做处理,下面这篇文章主要给大家介绍了关于C++ OpenCV裁剪图片时发生报错的解决方式,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • 解析c中stdout与stderr容易忽视的一些细节

    解析c中stdout与stderr容易忽视的一些细节

    本篇文章是对在c语言中stdout与stderr容易忽视的一些细节进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 用VC++6.0实现石头剪刀布游戏的程序

    用VC++6.0实现石头剪刀布游戏的程序

    最先看到这个游戏代码是python版的,后来看到有小伙伴用VC++重写了一遍,运行之后发现有些小bug,便尝试这修复了一下,并增加了些小功能,这里分享给大家。
    2015-03-03

最新评论