结构体重点知识大盘点

news2024/11/24 17:19:10

0、结构体基础知识

1、结构体是一些值的集合,这些值被称为成员,它们的类型是可以不同的。(与数组相似,但数组元素的类型都是相同的)。用来描述由基本数据类型组成的复杂类型。

2、结构体也有全局的和局部的。

3、struct+标签是一种结构体类型,可以用typedef重命名,以省略struct的书写。

1、结构体不完全声明

匿名结构体类型(省略标签)。(只想使用一次)

写结构体类型时直接创建变量,之后只能使用变量,无法找不到匿名结构体类型。 

值得注意的是:

struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}a[20], *p;

尽管两个匿名结构体的成员完全相同,将其  p=&x 的操作仍然不行(类型不兼容)。编译器认为它们并不是一种类型,结论是匿名结构体仅能使用一次。

2、结构体的自引用

在链表中,一个节点既要存储一个数据,又要能够找到下一个节点。

因此我们可以将每个节点的类型设置为结构体类型。

当我们在这个结构体类型中包含下一个节点的结构体时,会导致结构体的大小无限增大,为避免这一错误,并且顺利找到下一节点,我们可以创建一个结构体指针,指向下一个节点。

struct Node
{
int data;
struct Node next;
};

struct Node
{
int data;
struct Node* next;
}

注意:typedef重命名必须在一个类型已经完整定义后才能使用,否则将无法识别。

typedef struct Node
{
int data;
struct Node* next;
}Node;

 {}中的struct不可省略。

3、结构体变量的定义和初始化

结构体变量的定义有局部和全局。

初始化时类似数组,使用{},结构体内有其他结构体时,可以嵌套使用{}。

还可以乱序/不规则初始化,只需要 用   .找到相应成员,然后赋值即可。

struct Point
{
	int x;
	int y;
}p1 = {10, 20};

struct Point p2 = {0,0};

struct S
{
	int num;
	char ch;
	struct Point p;
	float d;
};

int main()
{
	struct Point p3 = {1,2};
	struct S s = { 100, 'w', {2,5}, 3.14f};
	struct S s2 = {.d=1.2f, .p.x=3,.p.y=5, .ch = 'q', .num=200};
	printf("%d %c %d %d %f\n", s.num, s.ch, s.p.x, s.p.y, s.d);
	printf("%d %c %d %d %f\n", s2.num, s2.ch, s2.p.x, s2.p.y, s2.d);
}

4、结构体重难点内存对齐

牺牲空间以换取时间、效率。

由于结构体存在内存对齐,我们在计算结构体大小时,不能简单的将其成员的类型所占大小简单的加和,而要考虑内存存储,以及CPU计算的知识。

结构体内存对齐规则:

1、结构体的第一个成员对齐到结构体在内存中存放位置的0偏移处。

2、对于之后的成员,每个成员都要对齐到一个对齐数的整数倍处。

这个对齐数是  成员自身大小和默认对齐数的较小值。

在VS环境下,默认对齐数是8,在Linux和gcc环境下无默认对齐数(为成员自身大小)

3、结构体的总大小为所有成员最大对齐数的整数倍

4、如果结构体中嵌套了结构体,要将嵌套的结构体对齐到它自己的成员中最大对齐数的整数倍处

第一个成员c1放在0偏移处(灰色部分)。 

i大小为4,默认对齐数为8,较小值为4,因此i对齐到4的倍数,从4开始存储(黄色部分)。

而蓝色部分123的空间会被浪费掉。(蓝色)

c2大小为1,因此对齐到1的倍数,即接着存放,放到8的位置(红色部分)。

此时结构体占用了9个字节。

所有成员的最大对齐数为4,结构体总大小为其整数倍,最后得到12byte

9-11的空间会被浪费掉(蓝色)

为观察成员在内存中的存储,我们可以用offsetof宏计算成员相对起始位置的偏移量。

 

简单记忆:先取小,再对齐存放,再取大,求总大小。 

结构体中包含一个结构体

内部的那个结构体,按照其成员中最大的对齐数 的整数倍来对齐。

最终结构体的总大小是所有对齐数中最大的那个的整数倍。

5、内存对齐的原因 

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

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

总结:除移植性外,内存对齐是为了读取时尽量一次读取完整,或每次读取都是有效的数据,当CPU进行无数次访问时,就会有效地提高性能、效率,空间换取时间。

当然,当成员顺序没有更多要求时,为了不浪费过多空间,我们在对结构体成员顺序的涉及上,可以将占用内存较小的成员集中放在一起,相当于将这些小成员替换到那些浪费的空间中。

6、修改默认对齐数

前面我们知道,VS中默认对齐数是8。但是某些情况下,经过我们的计算,可以将其修改。

利用#pragma预处理指令。

#pragma()为取消默认对齐数,里面放多少,就把默认对齐数修改为多少。

修改为1后,每个成员都是连续存放(即没有对齐)。当然,这种操作后可能会产生移植性的问题,以及性能降低的问题,为了避免,需要我们程序员进行相应的计算(按需更改)。

7、结构体传参 

结构体成员一般较多,结构体占用的内存空间也较大。

传结构体时,用结构体接收。  形参接收后用.访问结构体的成员。

传结构体的地址时,用相应结构体的指针来接收。用->访问结构体的成员。

函数传参时,参数需要压栈,就会有时间和空间上的系统开销。当传递的结构体对象较大时,系统开销就较大,进而使得性能下降。

因此,结构体传参时尽量传递地址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hello World with VS 17.4.4 DOT NET MAUI Note

Hello World with VS 17.4.4 DOT NET MAUI Note kagula2023-1-12 Prologue If you touched XAML, well here is a concise guide for you running the first MAUI project. Content System Requirement 【1】Microsoft Windows [Version 10.0.19044.2486] Chinese Language …

Ubuntu Centos Linux End Kernel panic-not syncing:Attempted to kill init!

原问题: 当前系统为 Ubuntu 解决问题步骤: 1、重启电脑,在进入选择版本时,选择 系统高级选项, 我选的是【Ubuntu高级选项】 2、进入一个又很多系统版本的界面,每个版本有三个选项:常规启动版…

如何在 ASP.NET Core 2.X 项目中通过EF Core使用MySQL数据库

目录 一、安装MySql.Data.EntityFrameworkCore 二、创建EF Core上下文类以及相关数据模型类 三、配置连接字符串 四、在Starup.cs中注册数据库服务(配置Context类的依赖注入) 五、通过数据迁移命令生成数据库 目前EF Core已经支持了MySQL数据库了。…

从零开始带你实现一套自己的CI/CD(四)Jenkins Pipeline流水线

目录一、简介二、Groovy2.1 HelloWorld2.2 Pipeline script from SCM三、Jenkinsfile3.1 拉取代码3.2 代码质量检测3.3 构建代码3.4 制作镜像并发布镜像仓库3.5 部署到目标服务器3.6 完整的Jenkinsfile3.7 参数配置3.8 通过参数构建四、添加邮件通知4.1 配置Jenkins邮件配置4.2…

开源飞控初探(一):无人机的历史

这章先纠正大疆带给无人机外行小白的认知。定义无人机无人机的正式英文名字是Unmanned Aerial Vehicle,缩写为UAV。有人无人的区分,是看飞机能否一直需要人为操控。最简单的场景是,当飞机飞出视线之外时,人已经很难实时根据环境来…

微服务自动化管理【docker compose】

1.什么是docker-compose Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排 通过编写docker-compose文件可对多个服务同时进行启动/停止/更新(可定义依赖,按顺序启动服务) docker-compose将所管理的容器分为3层结构&#…

Yii2下PHP远程调试PHP5.6/7.2与Xdebug2.5/2.7/3.0 在PHPSTORM下的差异化表现

学习起因:新人学YII2不知道远程调试(远程调试和控制台调试是两件事,同一个原理) 因为yii2框架,设计复杂度非常高,加上php代码的弱类型语言结构,在代码非常复杂的情况下,不采用调试的方式来看源码调用栈&am…

MPLS 虚拟专线 实验

目录 1.拓扑图 2.实验思路 3.主要配置 4.测试 5.实验总结 1.拓扑图 2.实验思路 IGP路由 MPLS Domain 配置MPLS VPN PE之间的MP-BGP邻居关系 CE端与PE端的路由交换 双向重发布,实现路由共享 3.主要配置 R6: *公网环境: [r6]ospf 1 r…

记录robosense RS-LIDAR-16使用过程2

一、安装并使用可视化工具RSView,官网提供了不同版本的安装包,根据个人环境下载解压。本人ubuntu18系统,修改权限:chmod ax run_rsview.sh;然后运行:./run_rsview.sh。该软件每次启动时都要运行./run_rsviewer.sh该软件…

Acwing 1214. 波动数列

题目链接&#xff1a;1214. 波动数列 - AcWing题库 标签&#xff1a;动态规划 &#xff08;字好丑...&#xff09; AC代码&#xff1a; #include<iostream> using namespace std;int f[1005][1005];const int MOD 100000007;//返回正余数 int get_mod(int a,int b) {…

不重复的随机数问题

前言 对于随机数的运用&#xff0c;在开发中经常会用到。有时需要生成不重复的定范围定总量的随机数&#xff0c;比如1~20&#xff0c;需要打乱的1~20中的10个数&#xff0c;那到底怎么做呢? 一、不重复的随机数 我们知道&#xff0c;直接用random会有重复的数字&#xff0…

电商物流云仓的原理是什么?

以云的速度和范围获得胜利  这是一个快速转型时期&#xff0c;封锁、就地避难订单和游览限制扰乱了美国经济的各个范畴&#xff0c;对供给链运营产生了严重影响。在如此动乱的时期&#xff0c;企业正越来越多地转向云优先战略&#xff0c;以使其供给链愈加矫捷和灵敏。  战…

【NI Multisim 14.0原理图文件管理——保存/备份文件及新建电路图页文件】

目录 序言 ⛄1.保存文件 ⛄2.备份文件 ⛄3.新建电路图页文件 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI Multisim 14.0&#xff0c;打开如图所示的启动界面&#xff…

CTK Plugin Framework插件框架学习--事件监听

文章目录一、前言二、框架事件三、插件事件四、服务事件五、添加事件监听一、前言 CTK一共有三种事件可以监听&#xff1a; 框架事件插件事件服务事件 但是这些事件只有在变化时才能监听到&#xff0c;如果已经变化过后&#xff0c;进入一个稳定的状态&#xff0c;这时才去监…

归并排序详细说明及实现-python

算法思想&#xff1a; 设初始序列含有n个记录&#xff0c;则可看成n个有序的子序列&#xff0c;每个子序列长度为1 两两合并&#xff0c;得到&#xff08;n//2) 个长度为2&#xff08;n为奇数时&#xff0c;最后一个序列的长度为1&#xff09;的有序子序列 再两两合并&#xff…

【Flink系列】开发篇:1. Flink维表关联方案

数据流往往需要访问外部的数据源来丰富自己的信息&#xff0c;比如通过record中的ip地址查询ip数据库maxmind的GeoIP2 Databases得到ip对应的城市名称&#xff0c;城市经纬度&#xff0c;将这些作为新的字段添加到原来的record中。这就涉及到本篇的主题&#xff1a;维表关联。 …

分布式锁方案分析:看图说话(图+文)

1 缘起 曾经在看分布式锁的时候&#xff0c;还是处于了解阶段&#xff0c; 回头总结时&#xff0c;发现有很多细节没有探究到&#xff0c; 本文以-看图说话的方式分析不同的分布式锁方案&#xff0c; 分布式锁需要保证&#xff1a; &#xff08;1&#xff09;互斥性&#xff1…

【从零开始学习深度学习】46. 目标检测中锚框的概念、计算方法、样本锚框标注方式及如何选取预测边界框

本文主要介绍目标检测中常用到的锚框相关概念、计算方式、样本标注及如何选取预测边界框并输出的相关内容。 目录1. 锚框介绍1.1 生成多个锚框2. 交并比--Jaccard系数3. 标注训练集的锚框4. 输出预测边界框---非极大值抑制方法总结1. 锚框介绍 在目标检测算法中通常会在输入图…

Linux常用命令——xhost命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) xhost 制哪些X客户端能够在X服务器上显示 补充说明 xhost命令是X服务器的访问控制工具&#xff0c;用来控制哪些X客户端能够在X服务器上显示。该命令必须从有显示连接的机器上运行。可以通过使用-host参数&…

​Topaz Photo AI 人工智能图像降噪锐化放大

Topaz Photo AI 是一款强大的基于人工智能技术的降噪、锐化及放大的工具。它不仅可以作为独立的软件使用&#xff0c;也可作为 Photoshop 的插件&#xff0c;以及能在 Lightroom Classic、Capture One 中调用。在 Lightroom Classic 中提供了两种工作流程&#xff0c;一种是直接…