自定义类型 (结构体)
文章目录
- 📬结构体的声明
- 🔎1.结构的基础知识
- 🔎2.结构的声明
- 🔎3.特殊的声明
- 🔎4.结构的自引用
- 🔎5.结构体变量的定义和初始化
- 🔎6.结构体内存对齐
- 🔎7.修改默认对齐数
- 🔎8.结构体传参
📬结构体的声明
🔎1.结构的基础知识
🚩 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
🔎2.结构的声明
🌰如描述学生👇
//定义学生类型
struct Stu
{//成员变量char name[20];int age;float weight;
}s4,s5,s6;//全局变量int main()
{struct Stu s1;//局部变量struct Stu s2;struct Stu s3;return 0;
}
🔎3.特殊的声明
🚩 在声明结构的时候,可以不完全的声明
👉匿名结构体类型👈
🌰举个例子👇
//匿名结构体类型
struct
{char c;int a;double d;
}s1;struct
{char c;int a;double d;
}a[20],*p;
上面的两个结构在声明的时候省略掉了结构体标签(tag)
❓问题来了
在上面代码的基础上,下面的代码合法吗?
p = &s1;
🚨编译器会把上面的两个声明当成完全不同的两个类型
🚨所以是非法的
🔎4.结构的自引用
在数据的存储中,可以使用顺序表的形式对数据进行存放;
顺序表,是计算机内存储存数据的一种方式;
即用一组地址连续的存储单元依次存储线性表中的各个元素;
而除了顺序表以外,还可以使用非顺序的形式的链表的方式对数据进行存储;
即使用不同的地址分别对数据进行存储,链表内的各个数据称为 “ 结点 ” ;
当需要使用或查找某个数据时,只需找到最初的结点即可访问需要访问的数据;

链表与顺序表都是以线性的方式对数据进行存储
若是使用结构体,如何创建一个简单的链表?
🚩在结构中包含一个类型为该结构本身的成员是否可以呢?
//错误示范
struct Node
{int data;struct Node next;
};
这样是否可以呢?
如果可以,那sizeof(struct Node)是多少呢?
上面的代码为创建一个结构体,并对结构体进行自引用达到通过一个数据访问下一个数据。
若是如此进行编译,在结构体内部的结构体变量还存在着一个结构体,周而复始,程序将会像死递归一样不停调用该结构体;
故该段代码为错误示范✖️。
正确的自引用方法✅👇
struct Node
{int data;//4struct Node* next;//4/8
};int main()
{struct Node n1;struct Node n2;n1.next = &n2;return 0;
}
🔎5.结构体变量的定义和初始化
🚩 请看代码(1)👇
struct S
{int a;char c;
}s1;struct S s3;struct B
{float f;struct S s;
};int main()
{struct S s2 = { 100,'q' };struct S s3 = { .c = 'r',.a = 2000 };struct B sb = { 3.14f,{200,'w'} };printf("%f,%d,%c\n", sb.f, sb.s.a, sb.s.c);return 0;
}

🚩 请看代码(2)👇
struct S
{char name[100];int* ptr;
};int main()
{int a = 100;struct S s = { "abcdef",NULL };return 0;
}
🔎6.结构体内存对齐
在声明结构体的时候,往往不同的结构体成员不同,结构体的大小也不同,若是存在以下的结构体,他们相应的大小是多少??
struct S1
{int a;char c;
};struct S2
{char c1;int a;char c2;
};struct S3
{char c1;int a;char c2;char c3;
};int main()
{printf("%d\n", sizeof(struct S1));printf("%d\n", sizeof(struct S2));printf("%d\n", sizeof(struct S3));return 0;
}
答案会是什么呢?
5 6 7 ???

那为什么和预想中的结果不一样呢?
🚩首先得掌握结构体的对齐规则:
🔴第一个成员在与结构体变量偏移量为0的地址处。
🔴其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
🔴对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。👉VS 中默认的值为8
👉Linux 中没有默认对齐数,对齐数就是成员自身的大小🔴结构体总大小为所有成员的对齐数中最大对齐数(每个成员变量都有一个对齐数)的整数倍。如果不够,则浪费空间对齐。
🔴如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
🔴如果嵌套了结构体,嵌套的结构体成员要对齐自己成员中的最大对齐数的整数倍处
🔴整个结构体大小,必须是最大对齐数的整数倍,最大对齐数包含嵌套的结构体成员中的对齐数


在这里我们可以使用offsetof宏来看一下各个成员的偏移量(使用offsetof求偏移量时,应包括头文件 <stddef.h> )
#include<stddef.h>struct S
{char c;int a;
};int main()
{struct S s = { 0 };printf("%d\n", offsetof(struct S, c));printf("%d\n", offsetof(struct S, a));return 0;
}

我们再看一个👇
struct S3
{double d;char c;int i;
};int main()
{printf("%d\n", sizeof(struct S3));return 0;
}


在上段代码的基础上,我们再来一个👇
struct S3
{double d;char c;int i;
};struct S4
{char c1;struct S3 s3;double d;
};int main()
{printf("%d\n", sizeof(struct S4));return 0;
}


🔴如果嵌套了结构体,嵌套的结构体成员要对齐自己成员中的最大对齐数的整数倍处
🔴整个结构体大小,必须是最大对齐数的整数倍,最大对齐数包含嵌套的结构体成员中的对齐数
为什么存在内存对齐?
1.平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常.
2.性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐;
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问.
🔴总体来说:
结构体的内存对齐是拿空间来换取时间的做法
在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
让占用空间小的成员尽量集中在一起
struct S1
{char c1;int i;char c2;
};
struct S2
{char c1;char c2;int i;
};
S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别
🔎7.修改默认对齐数
🚩使用 #pragma 这个预处理指令,可以改变我们的默认对齐数
👇请看代码与注释👇
#pragma pack(8)//设置默认对齐数为8struct S
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
🥰结论:
结构在对齐方式不合适的时候,我们可以自己更改默认对齐数
🔎8.结构体传参
struct S
{int data[1000];int num;
};struct S s = { {1,2,3,4},1000 };
//结构体传参
void printf1(struct S s)
{printf("%d\n", s.num);
}
//结构体地址传参
void printf1(const struct S* ps)
{printf("%d\n", ps->num);
}int main()
{print1(s);//传结构体print2(&s);//传地址return 0;
}
print2 相比于 print1 更好一些
原因:
🔴函数传参的时候,参数时需要压栈,会有时间和空间上的系统开销.
🔴如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降.
结论:
🔴结构体传参的时候,要传结构体的地址.
总结🥰
以上就是 自定义类型(结构体) 的内容啦🥳🥳🥳🥳
本文章所在【C语言知识篇】专栏,感兴趣的烙铁可以订阅本专栏哦🥳🥳🥳
前途很远,也很暗,但是不要怕,不怕的人面前才有路。💕💕💕
小的会继续学习,继续努力带来更好的作品😊😊😊
创作写文不易,还多请各位大佬uu们多多支持哦🥰🥰🥰
相关文章:
自定义类型 (结构体)
文章目录📬结构体的声明🔎1.结构的基础知识🔎2.结构的声明🔎3.特殊的声明🔎4.结构的自引用🔎5.结构体变量的定义和初始化🔎6.结构体内存对齐🔎7.修改默认对齐数🔎8.结构体…...
第14届蓝桥杯STEMA测评真题剖析-2023年3月12日Scratch编程初中级组
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第113讲。 蓝桥杯选拔赛现已更名为STEMA,即STEM 能力测试,是蓝桥杯大赛组委会与美国普林斯顿多…...
程序员接私活一定要知道的事情,我走的弯路你们都别走了
文章目录前言一、程序员私活的种类1.兼职职位众包2.自由职业者驻场3.项目整包二、这3种私活可以接1.有熟人2.七分熟的项目3.需求明确的项目三、这3种私活不要接1.主动找上门的中介单2.一味强调项目简单好做3.外行人给你拉的项目四、接单的渠道1.线下渠道2.线上渠道3.比较靠谱的…...
十二届蓝桥杯省赛c++(下)
1、 拿到题目一定要读懂题意,不要看到这题目就上来模拟什么闰年,一月的天数啥的。这个题目问你当天的时间,就说明年月日跟你都没关系,直接无视就好了。 #include <iostream> #include <cstring> #include <algori…...
数据结构与算法——堆的基本存储
目录 一、概念及其介绍 二、适用说明 三、结构图示 四、Java 实例代码 五.堆和栈的区别 一、概念及其介绍 堆(Heap)是计算机科学中一类特殊的数据结构的统称。 堆通常是一个可以被看做一棵完全二叉树的数组对象。 堆满足下列性质: 堆中某个节点的值总是不大…...
来了来了 !!!K8s指令、yaml部署
文章目录k8s资源清单一、k8s资源指令1、基础操作2、命令手册二、资源清单1、required2、optional3、other4、资源清单格式5、常用命令三、部署实例1、nginx3、eureka部署k8s资源清单 一、k8s资源指令 1、基础操作 #创建且运行一个pod #deployment、rs、pod被自动创建 kubect…...
spring-cloud-feign实战笔记
feign 配置 针对单个feign接口进行配置feign:client:config:# feignName 注意这里与contextId一致,不能写成name(FeignClientFactoryBean#configureFeign)# 不能写成 client-b (微服务名称),否则不生效helloFeignClient: # conte…...
【Pytorch】利用PyTorch实现图像识别
本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052 这是目录使用torchvision库的datasets类加载常用的数据集或自定义数据集使用torchvision库进行数据增强和变换,自定义自己的图像分类数据集并使用torchvision库加载它们使…...
在家查找下载最新《柳叶刀》The Lancet期刊文献的方法
《柳叶刀》The Lancet简介: 《柳叶刀》The Lancet是全球顶尖综合性医学期刊,每周都会发表来自世界各地顶尖科学家的研究精粹。是由托马斯威克利(Thomas Wakley)创办于1823年,由爱思唯尔(Elsevierÿ…...
当下的网络安全行业前景到底怎么样?还能否入行?
前言网络安全现在是朝阳行业,缺口是很大。不过网络安全行业就是需要技术很多的人达不到企业要求才导致人才缺口大常听到很多人不知道学习网络安全能做什么,发展前景好吗?今天我就在这里给大家介绍一下。网络安全作为目前比较火的朝阳行业&…...
SpringCloud:SpringAMQP介绍
Spring AMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。Spring AMQP官方地址 Spring AMQP提供了三个功能: 自动声明队列、交换机及其绑定关系基于注解的监听器模式,异步接收消息封…...
第十三届蓝桥杯省赛 python B组复盘
文章目录前言主要内容🦞试题 A:排列字母思路代码🦞试题 B:寻找整数思路代码🦞试题 C:纸张尺寸思路代码🦞试题 D:数位排序思路代码🦞试题 E:蜂巢思路代码&…...
SQL注入之HTTP请求头注入
Ps: 先做实验,在有操作的基础上理解原理会更清晰更深入。 一、实验 sqli-lab 1. User-Agent注入 特点:登陆后返回用户的 User-Agent --> 服务器端可能记录用户User-Agent 输入不合法数据报错 payload: and updatexml(1,concat("~&…...
Metasploit详细教程
第一步:安装和启动Metasploit 您可以从Metasploit官方网站下载适用于您操作系统的Metasploit框架。安装Metasploit框架后,您可以使用以下命令来启动Metasploit: msfconsole该命令将启动Metasploit控制台。 第二步:查找目标设备…...
【ChatGPT】Notion AI 从注册到体验:如何免费使用
欢迎关注【youcans的GPT学习笔记】原创作品,火热更新中 【ChatGPT】Notion AI 从注册到体验1. Notion AI 介绍1.1 Notion AI 简介1.2 Notion AI 的核心能力1.3 Notion AI 与 ChatGPT 的比较2. Notion AI 国内用户注册2.1 PC 端用户注册2.2 移动端用户注册3. Notion …...
每个开发人员都需要掌握的10 个基本 SQL 命令
SQL 是一种非常常见但功能强大的工具,它可以帮助从任何数据库中提取、转换和加载数据。数据查询的本质在于SQL。随着公司和组织发现自己处理的数据量迅速增加,开发人员越来越需要有效地使用数据库来处理这些数据。所以想要暗恋数据领域,SQL是…...
Vue项目预渲染
前言 Ajax 技术的出现,让我们的 Web 应用能够在不刷新的状态下显示不同页面的内容,这就是单页应用。在一个单页应用中,往往只有一个 html 文件,然后根据访问的 url 来匹配对应的路由脚本,动态地渲染页面内容。单页应用…...
可别再用BeanUtils了(性能拉胯),试试这款转换神器
老铁们是不是经常为写一些实体转换的原始代码感到头疼,尤其是实体字段特别多的时候。有的人会说,我直接使用get/set方法。没错,get/set方法的确可以解决,而且也是性能较高的处理方法,但是大家有没有想过,要…...
Transformer 杂记
Transformer输入的是token,来自语言序列的启发。卷积神经网络(CNN)是如何进行物种分类的.它实际是直接对特征进行识别,也就是卷积神经网络最基本的作用:提取图像的特征。例如:卷积神经网络判断一只狗的时候,…...
实现异步的8种方式
前言异步执行对于开发者来说并不陌生,在实际的开发过程中,很多场景多会使用到异步,相比同步执行,异步可以大大缩短请求链路耗时时间,比如:「发送短信、邮件、异步更新等」,这些都是典型的可以通…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
