结构体

  • 结构体类型的声明
  • 结构体自引用
  • 结构体变量的定义和初始化
  • 结构体内存对齐
  • 结构体传参

结构体


  1. 结构体的声明
    结构体是一些值集合的,里面可以包括char,int,double等等的各种类型构成的一个新的类型,也就是说相当于自己基于C语言本身给出的类型自己把它组成一个集合。
    它的声明格式如下:
struct 类型名{元素1;元素2;.....
};

例如描述一个学生:

struct  stu
{char name[20];//名字int age;//年龄char ID[20];//学号
};
  1. 结构体的自引用
    我们知道结构体里面可以包括char,int ,double等等类型,那么通过上面我们讲的结构体它也是一种类型。只不过是我们自己定义的一种类型,那么我们可以在结构体里面定义一个结构体吗?
    先说结果:不可以!!!
    话不多说我直接上机测试给大家看>
struct  stu
{char name[20];//名字int age;//年龄char ID[20];//学号struct stu next;
};

如果我们这样写我们用VS2019运行后的结果如下>

这里我们可以知道直接定义是不行的。
那么正确的自引用方式是下面这个>

struct  stu
{char name[20];//名字int age;//年龄char ID[20];//学号struct stu *next;
};

这里我们要自引用的话,需要在struct stu后加上“ * ”让它成为一个结构体指针,它的用法和解释涉及指针和链表知识这里不展开讲,感兴趣的小伙伴可以自行查找资料阅读或者看我下期。

  1. 结构体变量的定义和初始化
    有了结构体类型,那如何定义变量,其实很简单。
struct  stu
{char name[20];//名字int age;//年龄char ID[20];//学号
}s1,s2;         //直接在结构体类型声明后直接定义struct stu s1, s2;     //定义结构体struct stu s3 = { "张三",18,2022001 };//定义后直接初始化struct nau{int num;//号数char name[20];//名字} a1={18,"李四"};//直接在结构体类型声明后直接定义并初始化struct cmp{int i;struct nau;//结构体嵌套初始化}p1 = { 1,{18,"丽子"} };
  1. 结构体内存对齐
    基本了解结构体的内容之后,我们就要计算结构体的大小了。
    这也是一个特别热门的考点:
    那么我们直接上几道练习
#include<stdio.h>
struct s
{char i;char j;int a;
}s1;
struct c
{char b;int b1;char b2;
}s2;
int main()
{printf("%d\n", sizeof(s1));//大小是多少呢? printf("%d\n", sizeof(s2));//大小是多少呢?return 0;
}

我当初没学的时候是这样分析的:第一个和第二个都是有两个char类型占2个字节,然后一个int类型占4个字节,加起来就是6个字节嘛!!

然而结果真的是这样吗?
运行程序之后你会发现一个答案是8,一个是12;

如何计算?
首先得掌握结构体的对齐规则:

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

为什么存在内存对齐?

大部分的参考资料都是这样说的:

  1. 平台原因(移植原因):
    不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特
    定类型的数据,否则抛出硬件异常。

  2. 性能原因:
    数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
    原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访
    问。

简单来说就是用空间换取时间

那在设计结构体的时候,我们既要满足对齐,又要节省空间,我们要 让占用空间小的成员尽量集中在一起

就像上面两个结构体,我们尽量使用第一个比较省空间
感兴趣的小伙伴可以尝试做一下下面这些题(答案在下方)

struct S3
{double d;  //练习1char c;int i;
};
printf("%d\n", sizeof(struct S3));//练习2-结构体嵌套问题
struct S4
{char c1;struct S3 s3;double d;
};
printf("%d\n", sizeof(struct S4));

答案:
上面s3的大小是16
s4的大小是32

  1. 结构体传参

我上几期发布过一个结构体数组的运用,里面包括了结构体传参,这里就不展开讲了结构体数组的定义和使用


细讲C语言结构体(结构体内存对齐你懂了吗?)相关推荐

  1. c语言 char转int_图文并茂,一文讲透C语言结构体内存对齐

    ↑点击上方蓝色字体,关注"嵌入式软件实战派"获得更多精品干货. (以下有约5000字内容,建议收藏再读,推荐下载源码自行测试以加深理解.) 面试官:你知道C语言的结构体对齐吗? 应 ...

  2. 语言结构体在内存的分布_结构体内存对齐,这篇文章给你彻底搞会!(干货收藏)...

    脚本之家 你与百万开发者在一起 公众号:C语言编程 作者:薛定谔的coding猫 一.内存对齐的原因  1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上 ...

  3. 【C语言】一文搞定如何计算结构体的大小----结构体内存对齐规则

    要搞定如何正确地计算一个结构体的大小,我们就要深刻理解结构体内存对齐规则: 结构体内存对齐规则: 1.结构体的第一个成员永远在结构体起始位置偏移量为0的位置: 2.结构体成员从第二个成员开始,总是放在 ...

  4. 关于C语言中的结构体内存对齐与位段问题

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 结构体的内存对齐与位段 一.结构体的内存对齐 1.为什么会有内存对齐? 2.如何内存对齐 3. 如何在设计结构体的时候,既要 ...

  5. c#往结构体里面读数据_结构体内存对齐,这回给你彻底搞会!

    一.内存对齐的原因  1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上的任意数据:某些硬件平台只能在某些特定地址处取某些特定的数据,否则就会抛出硬件异常 ...

  6. printf打印结构体_工程师:这道题80%初学者都没做对!你确定搞懂结构体内存对齐了?...

    这是工程师面试后的实际经历-- 这道经典.易错的关于C语言结构体内存对齐的题目,你真的会吗: 求32bit环境下以下结构体所占的字节数:typedef struct test_struct{ char ...

  7. C语言结构体内存对齐问题

    参考博文:C语言结构体内存对齐问题 成员对齐:   以4字节对齐为例,如果自身类型小于4字节,则该成员的首地址是自身类型大小的整数倍:如果自身类型大于等于4字节,则该成员的首地址是4的整数倍.若内嵌结 ...

  8. 室友利用一把王者的时间就学会了【C语言结构体内存对齐】

    文章目录 一.什么是结构体内存对齐? 二.结构体的对齐规则 结构体内存对齐规则的具体应用 三.为什么会存在内存对齐 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一.什么是结构体内存对齐? 从 ...

  9. 【C语言】自定义类型——计算结构体内存对齐

    文章目录 前言 一.结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 *结构体内存对齐 修改默认对齐数 结构体传参 结构体实现位段(位段的填充&可移植性) 二.枚举 枚举类型的 ...

最新文章

  1. docker 端口被占用问题解决
  2. [Android 插件化(二)] DroidPlugin 用法
  3. 下pg负载均衡_SAE 场景下,应用流量的负载均衡及路由策略配置实践
  4. python 字典取值的时间复杂度_五道常见的Python面试题一定不要答错!
  5. HDU 1476 Sudoku Killer
  6. verilog异步复位jk触发器_HDLBits: 在线学习Verilog(Problem 120-126)
  7. module 'inn' not found:No LuaRocks module found for inn
  8. 如何安装boost库
  9. 【令人头秃的线段树】线段树入门题目详解(代码逐句分析)
  10. Oracle数据库基础入门视频合集
  11. java输入、输出流的简单入门
  12. iphone 计算文件长度
  13. 论文笔记(一)《Intriguing properties of neural networks》
  14. Duilib corner属性
  15. kafka 使用及学习过程中的爬坑记录
  16. Gogs生产环境搭建和数据迁移指南
  17. Installation of packages ‘stringi’ had non-zero exit status
  18. 怀旧服服务器最新动态,永久60级怀旧服将于20日合服 服务器合并详情
  19. 多益网络2020笔试题
  20. html5导航 按钮,CSS实例:超酷的网站导航按钮

热门文章

  1. 技术:Vue express-generator生成器,分享一句话
  2. 洗脸的诀窍 女生变漂亮 男生变帅气
  3. python按内容分割txt文件_Python实现逐行分割大txt文件示例详解
  4. datename和datepart
  5. Golang实现MySQL数据库备份
  6. intel 服务器主板芯片,台积电3nm制程获Intel订单,不打造手机芯片太可惜了
  7. X的旅游计划 C语言 SDUT
  8. android.policy.jar t8830pro,华为t8830pro刷机教程
  9. 计算机操作业务知识试题及答案,全国计算机等级考试一级考试练习(新大纲)试题及答案(一)...
  10. HTML5画布椭圆形教程