• 快来!!!学弟的这篇结构体让学姐老脸一红!!!



    前言

    相信大家在c语言自定义的学习过程中,离不开结构体,并且大为头疼!!别慌来看这篇文章,由浅入深干翻结构体!!!


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、结构体的声明

    结构:结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量!!!

    1.结构的声明

    suruct  name

    {

            member-list;

    }variable-list

    例如描述一个家庭:

    1. struct Famliy
    2. {
    3. char name_mom[20];
    4. char name_father[20];
    5. char name_son[20];
    6. char name_dog[20];
    7. };//此处的分号不能丢!!!!!

    2.特殊的声明(匿名结构体类型)

    1. struct
    2. {
    3. int a;
    4. int b;
    5. char c;
    6. }x;
    7. struct
    8. {
    9. int a;
    10. int b;
    11. char c;
    12. }a[20],*p;

    上述两个匿名结构体类型都省略掉了结构体标签tag

    那么在上述代码中!!!

    p=&x;//这段代码是否合法???

    答案显然是错误的我们稍加调试就可以知道,这是不可以的,编译器会自动将上面两个类型当成两个不同的类型。所以是非法的

    3.结构的自引用

    当我们使用结构体时,如果需要在结构中存放一个与刚开始一样的结构体变量那么我们看图:

     

    当此时!!!struct里面存放了struct,此循环无穷无尽,无法算出此结构体类型的大小,因此,我们在此时,需要存放结构体指针!!!如图:

     4.结构体变量的定义和初始化

    有了结构体变量类型之后,定义变量,就变得容易了很多!!!

    1. struct Point
    2. {
    3. int x;
    4. int y; }p1; //声明类型的同时定义变量p1
    5. struct Point p2; //定义结构体变量p2

    p1,p2此时都是全局变量,大家可以自行选择方式定义结构体变量

    要是想边定义变赋值,这当然也可以!!!

    // 初始化:定义变量的同时赋初值。
    struct Point p3 = {x, y}
    1. struct Point p3 = {x, y};
    2. struct Stu        //类型声明
    3. {
    4. char name[15];//名字
    5. int age;      //年龄
    6. };
    struct Stu s = {"zhangsan", 20};//初始化
    1. struct Node
    2. {
    3. int data;
    4. struct Point p;
    5. struct Node* next;
    6. }n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
    struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

    5.结构体的内存对齐

    用途:计算结构体的大小(重点)

     第一题看起来很简单1+4+1=6,第二题1+1+4=1,第三题8+1+4=13

    然而并非如此!!!

    1. //练习1
    2. struct S1
    3. {
    4. char c1;
    5. int i;
    6. char c2;
    7. };
    8. printf("%d\n", sizeof(struct S1))
    1. //练习2
    2. struct S2
    3. {
    4. char c1;
    5. char c2;
    6. int i;
    7. };
    8. printf("%d\n", sizeof(struct S2));

    1. //练习3
    2. struct S3
    3. {
    4. double d;
    5. char c;
    6. int i;
    7. };
    8. printf("%d\n", sizeof(struct S3));

    1. //练习4-结构体嵌套问题
    2. struct S4
    3. {
    4. char c1;
    5. struct S3 s3;
    6. double d;
    7. };
    8. printf("%d\n", sizeofstruct S4));

    此时会出现著名的结构体内存对齐!!!划重点

    要知道如何计算结构体对齐数,我们需要知道结构体对齐规则

    1. 第一个成员在与结构体变量偏移量为 0 的地址处。
    2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的 较小值
    VS 中默认的值为 8
    3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
    4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
    例1:

    例2:

     例三例四也是同理!!

    为什么存在内存对齐 ?
    大部分的参考资料都是如是说的:
    1. 平台原因 ( 移植原因 )
    不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特
    定类型的数据,否则抛出硬件异常。
    2. 性能原因
    数据结构 ( 尤其是栈 ) 应该尽可能地在自然边界上对齐。
    原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访
    问。
    总体来说:
    结构体的内存对齐是拿 空间 来换取 时间 的做法。
    那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
    让占用空间小的成员尽量集中在一起。


    总结

    这里我们介绍了结构体类型!!!

    希望大家都能完美掌握!!!

  • 相关阅读:
    Java泛型
    如何在 SAP Spartacus 中编写 ASM-Compatible 的代码
    【字符串与日期的相互转换NSDate Objective-C语言】
    如何使用CSS伪类选择器
    idea:如何连接数据库
    割草机器人芯片选型及各厂家产品对比
    【实战详解】如何快速搭建接口自动化测试框架?Python + Requests
    MySQL下载与安装
    HiveSQL中的JOIN ON条件
    深入解析大数据分析:技术挑战、应用场景与未来趋势
  • 原文地址:https://blog.csdn.net/m0_72018048/article/details/126920001