当前位置: 首页 > news >正文

自定义类型 (结构体)

文章目录

  • 📬结构体的声明
    • 🔎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们多多支持哦🥰🥰🥰

请添加图片描述

相关文章:

自定义类型 (结构体)

文章目录&#x1f4ec;结构体的声明&#x1f50e;1.结构的基础知识&#x1f50e;2.结构的声明&#x1f50e;3.特殊的声明&#x1f50e;4.结构的自引用&#x1f50e;5.结构体变量的定义和初始化&#x1f50e;6.结构体内存对齐&#x1f50e;7.修改默认对齐数&#x1f50e;8.结构体…...

第14届蓝桥杯STEMA测评真题剖析-2023年3月12日Scratch编程初中级组

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第113讲。 蓝桥杯选拔赛现已更名为STEMA&#xff0c;即STEM 能力测试&#xff0c;是蓝桥杯大赛组委会与美国普林斯顿多…...

程序员接私活一定要知道的事情,我走的弯路你们都别走了

文章目录前言一、程序员私活的种类1.兼职职位众包2.自由职业者驻场3.项目整包二、这3种私活可以接1.有熟人2.七分熟的项目3.需求明确的项目三、这3种私活不要接1.主动找上门的中介单2.一味强调项目简单好做3.外行人给你拉的项目四、接单的渠道1.线下渠道2.线上渠道3.比较靠谱的…...

十二届蓝桥杯省赛c++(下)

1、 拿到题目一定要读懂题意&#xff0c;不要看到这题目就上来模拟什么闰年&#xff0c;一月的天数啥的。这个题目问你当天的时间&#xff0c;就说明年月日跟你都没关系&#xff0c;直接无视就好了。 #include <iostream> #include <cstring> #include <algori…...

数据结构与算法——堆的基本存储

目录 一、概念及其介绍 二、适用说明 三、结构图示 四、Java 实例代码 五.堆和栈的区别 一、概念及其介绍 堆(Heap)是计算机科学中一类特殊的数据结构的统称。 堆通常是一个可以被看做一棵完全二叉树的数组对象。 堆满足下列性质&#xff1a; 堆中某个节点的值总是不大…...

来了来了 !!!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一致&#xff0c;不能写成name&#xff08;FeignClientFactoryBean#configureFeign&#xff09;# 不能写成 client-b (微服务名称)&#xff0c;否则不生效helloFeignClient: # conte…...

【Pytorch】利用PyTorch实现图像识别

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 这是目录使用torchvision库的datasets类加载常用的数据集或自定义数据集使用torchvision库进行数据增强和变换&#xff0c;自定义自己的图像分类数据集并使用torchvision库加载它们使…...

在家查找下载最新《柳叶刀》The Lancet期刊文献的方法

《柳叶刀》The Lancet简介&#xff1a; 《柳叶刀》The Lancet是全球顶尖综合性医学期刊&#xff0c;每周都会发表来自世界各地顶尖科学家的研究精粹。是由托马斯威克利&#xff08;Thomas Wakley&#xff09;创办于1823年&#xff0c;由爱思唯尔&#xff08;Elsevier&#xff…...

当下的网络安全行业前景到底怎么样?还能否入行?

前言网络安全现在是朝阳行业&#xff0c;缺口是很大。不过网络安全行业就是需要技术很多的人达不到企业要求才导致人才缺口大常听到很多人不知道学习网络安全能做什么&#xff0c;发展前景好吗&#xff1f;今天我就在这里给大家介绍一下。网络安全作为目前比较火的朝阳行业&…...

SpringCloud:SpringAMQP介绍

Spring AMQP是基于RabbitMQ封装的一套模板&#xff0c;并且还利用SpringBoot对其实现了自动装配&#xff0c;使用起来非常方便。Spring AMQP官方地址 Spring AMQP提供了三个功能&#xff1a; 自动声明队列、交换机及其绑定关系基于注解的监听器模式&#xff0c;异步接收消息封…...

第十三届蓝桥杯省赛 python B组复盘

文章目录前言主要内容&#x1f99e;试题 A&#xff1a;排列字母思路代码&#x1f99e;试题 B&#xff1a;寻找整数思路代码&#x1f99e;试题 C&#xff1a;纸张尺寸思路代码&#x1f99e;试题 D&#xff1a;数位排序思路代码&#x1f99e;试题 E&#xff1a;蜂巢思路代码&…...

SQL注入之HTTP请求头注入

Ps&#xff1a; 先做实验&#xff0c;在有操作的基础上理解原理会更清晰更深入。 一、实验 sqli-lab 1. User-Agent注入 特点&#xff1a;登陆后返回用户的 User-Agent --> 服务器端可能记录用户User-Agent 输入不合法数据报错 payload: and updatexml(1,concat("~&…...

Metasploit详细教程

第一步&#xff1a;安装和启动Metasploit 您可以从Metasploit官方网站下载适用于您操作系统的Metasploit框架。安装Metasploit框架后&#xff0c;您可以使用以下命令来启动Metasploit&#xff1a; msfconsole该命令将启动Metasploit控制台。 第二步&#xff1a;查找目标设备…...

【ChatGPT】Notion AI 从注册到体验:如何免费使用

欢迎关注【youcans的GPT学习笔记】原创作品&#xff0c;火热更新中 【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 是一种非常常见但功能强大的工具&#xff0c;它可以帮助从任何数据库中提取、转换和加载数据。数据查询的本质在于SQL。随着公司和组织发现自己处理的数据量迅速增加&#xff0c;开发人员越来越需要有效地使用数据库来处理这些数据。所以想要暗恋数据领域&#xff0c;SQL是…...

Vue项目预渲染

前言 Ajax 技术的出现&#xff0c;让我们的 Web 应用能够在不刷新的状态下显示不同页面的内容&#xff0c;这就是单页应用。在一个单页应用中&#xff0c;往往只有一个 html 文件&#xff0c;然后根据访问的 url 来匹配对应的路由脚本&#xff0c;动态地渲染页面内容。单页应用…...

可别再用BeanUtils了(性能拉胯),试试这款转换神器

老铁们是不是经常为写一些实体转换的原始代码感到头疼&#xff0c;尤其是实体字段特别多的时候。有的人会说&#xff0c;我直接使用get/set方法。没错&#xff0c;get/set方法的确可以解决&#xff0c;而且也是性能较高的处理方法&#xff0c;但是大家有没有想过&#xff0c;要…...

Transformer 杂记

Transformer输入的是token,来自语言序列的启发。卷积神经网络&#xff08;CNN&#xff09;是如何进行物种分类的.它实际是直接对特征进行识别&#xff0c;也就是卷积神经网络最基本的作用&#xff1a;提取图像的特征。例如&#xff1a;卷积神经网络判断一只狗的时候&#xff0c…...

实现异步的8种方式

前言异步执行对于开发者来说并不陌生&#xff0c;在实际的开发过程中&#xff0c;很多场景多会使用到异步&#xff0c;相比同步执行&#xff0c;异步可以大大缩短请求链路耗时时间&#xff0c;比如&#xff1a;「发送短信、邮件、异步更新等」&#xff0c;这些都是典型的可以通…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...