结构体的初步认识以及其内存的计算

article/2025/10/15 4:21:00

目录

前言

结构体的定义

结构体的自引用

 结构体的初始化

 结构体内存的计算


前言

我们知道,通过不同的数据类型我们可以表达不同意义的数据,如长度宽度面积只需要定义一个 int 类型的数据就可以符合大部分的需求。但是,有些东西自存在就是一种集合体,如一个人(他有身高、体重、姓名、爱好等等)一本书(有内容、价格、作者、出版社等等)。如果我们要表达这样的一个存在,以以前的数据结构便无法准确地将其表达。便存在一种拥有多种数据的集合,便叫作结构体。

结构体的定义

  这样子便是一个结构体在函数外部的声明,我们可以在函数外定义全局变量,也可以在函数内定义局部变量。不仅如此还有另一种写法叫做匿名结构体类型,就是在声明是时候不加上结构体标签,但是要在结尾加上定义变量的名称。

 这样写的有一个不利因素就是,在函数之中要使用的时候定义了几个结构体变量就只能使用几个该结构体。

这时候我们想到,如果这样定义了两个结构体,他们的内容完全一样,那这两个结构体是等价的吗?

 运行起来编译器就报错了,即便是内部定义的内容完全一样,但是从编译器的视角来说,这两个结构体并不是同一类型的东西。

结构体的自引用

当我们想要在一个结构体中再包含一个同类型的结构体。

 如此,便会看到编译器给我们报了错误,这个语法本身就是错误的,况且当一个结构体类型内部包含了另一个结构体类型,如此一环套一环,这样我们便无法计算这个结构体的具体大小了。

正确定义的方式应该是这样子,next 表示指向结构体的结构体指针,如此便可以正确定义。

 结构体的初始化

定义完结构体,如果不进行初始化也无法使用。结构体的初始化也十分地简单,只需要在主函数中定义是在后面用大括号进行初始化。

 也可以在定义结构体是直接进行初始化,最终的结果都是一样,只不过前者属于局部变量而后者属于全局变量。

 但是我们是可以在一个结构体中嵌套调用另外一个结构体的。 

 在定义如此结构体的时候也需要嵌套使用两个{ } ,第一个大括号表示我们对所定义的这个结构体也就是 s 进行初始化,第二个大括号则表示对内部嵌套调用的结构体进行初始化。

 结构体内存的计算

我们来看这串代码,我们定义了两个结构体变量,内容上的区别只有不同数据类型的排放顺序不同,但是这两个结构体的所占内存的大小好像有所不同。

 从结果上看,两个结构体所占的内存并不相同。为什么会出现这种情况呢?我们需要了解结构体内存补齐的机制。

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

之所以存在内存补齐的机制,是为了保证在读取的时候可以完整地读取每个数据,因而对内存进行的修饰。即耗费了内存但是大大地增加了代码运行的速率。

既然已经知道了内存补齐的规律,那我们来分析一下上面的代码。c1由于只有一个字节因此刚开始对齐于与结构体变量偏移量为0的地址处,第二个数据为 int 类型的数据,根据规律其他成员变量要对齐到对齐数的整数倍的地址处,而 int 类型数据的对齐数为4,因此 i 应该对齐到偏移为4的位置。第三个数据类型为 char 对齐数为 1 因而直接对齐于偏移为8的位置,这还没完,结构体总大小为最大对齐数的整数倍。目前位置所占大小为9,最大的对齐数为4,所以要再次进行补齐。即最后的内存大小为12。

 同理,第二个结构体,用同样的方法进行推理便可以得到下面的结果。所以总的内存便占了8个字节。

 如果喜欢本篇文章就留下个赞吧,关注博主不迷路,也欢迎大家在评论区留言讨论,谢谢大家。


http://chatgpt.dhexx.cn/article/6T2mklk5.shtml

相关文章

IDA创建结构体方法

1. ida是最好用的逆向分析工具 2.问题 如果你在使用IDA分析时遇到大量的结构体指针偏移形式的变量,肯定想根据自己的分析重命名结构体各项。 3.定义结构体 这是需要先找到结构体初始化的地方 这里记录了每一项的偏移量,记录了结构体总大小Ox110uLL。 …

手把手教你写单片机的结构体

手把手教你写单片机的结构体 摘要:听说还有好多学单片机的小伙伴不会用结构体?指针和结构体是学单片机必须要掌握的,如果你C语言掌握的不牢,单片机根本学不到精髓,只能完成一些低级的项目。看得懂结构体并且能够灵活运…

STM32基于Flash对结构体读写暨再认识结构体内存分配

目录 前言 认识结构体内存分布 模拟结构体搬运 实现FLASH的结构体读写 前言 记录本篇主要是记录我进行stm32学习中利用stm32的flash(闪存)读写结构体的总结。 认识结构体内存分布 结构体,主要要来存放我们的自定义类型的数据,结…

单片机的结构体

手把手教你写单片机的结构体 FROM8号线攻城狮 公众号 电子信息工程硕士在读,分享单片机、嵌入式linux、物联网等知识,致力于打造最硬核的嵌入式技术公众号。 半碗鸡汤,半碗杂粮。 摘要:听说还有好多学单片机的小伙伴不会用结构…

windows下mysql初始密码设置

转载自:http://blog.csdn.net/ofreelander/article/details/50802780 1.my-default.ini 改名my.ini 在解压的目录下面复制my-default.ini一份改名字为 my.ini。 2.打开 Windows 环境变量设置, 新建变量名 MYSQL_HOME , 变量值为 MySQL 安装目录路径, 在 环境变量 …

MYSQL修改初始化密码的方法

解决方法之一: “ ALTER USER rootlocalhost identified by 123456 ; ” 最近安装了mysql,在使用“ set password for rootlocalhostpassword(123456);”时会遇到 “ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that…

Centos下安装mysql查看初始密码并修改密码

题记:当我们在centos成功安装了mysql后,需要查看初始密码,大概率也需要自己修改密码。 一,查看mysql历时密码 cat var/log/mysqld.log二,进入到mysql mysql -u root -p按回车,然后再password:输入刚才所…

MySQL设置初始密码—注意版本mysql-8.0.30

MySQL设置初始密码—注意版本mysql-8.0.30 第一步:使用管理员模式下的命令行,进入mysql的所在文件下的bin目录; 第二步:输入命令mysql -u root -p; 第三步:这里第一次不用输入密码; 第四步: ALTER USER rootlocalhost…

安装mysql的初始密码在哪里

mysql初始密码是多少 介绍怎么找到mysql安装的root的初始密码 mysql初始密码是多少 介绍怎么找到mysql安装的root的初始密码 怎么给mysql设置用户名和密码 登录数据库 “命令提示字符”窗口录入, 录入cd C:\mysql\bin 并按下回车键,将目录切换为 cd C:\m…

关于MySQL初始化密码忘记的问题

本文章可以解决MySQL密码忘记的问题!!! 1、到mysql安装的bin目录下运行PowerShell 2、在命令行输入 mysql -u root -p 登录 mysql,可以随意输入一个密码,返回”ERROR 1045 (28000): Access denied for user rootlocal…

mysql安装,以及初始化密码

1.首先下载 mysql安装包, 我这里下载的mysql 5.7(免安装版) https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-winx64.zip 然后解压到你自己的目录中,我这里为 D 盘下: 此处,下下来的压缩包里面, data 目…

mysql初始没有密码怎么设置

由于本人是win7的忠实用户,最近被win10所吸引索性换了系统,还是改不了恋旧的习惯。所以用的mysql还是5.6。进入正题 在装完mysql并且配置完环境变量之后发现密码为空 1.首先进入到你安装的目录下,这里我的是E盘 2.之后输入mysql -u root -p …

1、数据库-MySql

什么是数据库 数据库(DataBase,简称DB) 概念:长期存放在计算机内,有组织,可共享的大量数据的集合,是一个数据"仓库" 作用:保存,并能安全管理数据(如:增删改查等),减少冗余… 数据…

C++中字符串大小写字母转换

最近在学习 STL,string 也是 STL 中的一种容器,遇到一个字符串中字母大小写转换的例子,这里就顺便总结一下在C中常用的字符串大小写转换方法,有需要的可以参考。代码如下: 1、char[]类型,调用库函数 // …

大小写字母转换(java大小写字母转换)

苹果4SQQ密码大小写字母怎么转换不?苹果4SQQ密码大小写字母 每次要输密码,当时在电脑上设置的密码,可以改变大小写,但是到了手机上,我不知道怎么换大小写,那位朋友告诉下 苹果手机输入法怎么改字母的大小写 (很高兴为您解答,有帮助请给好评,谢谢! ) 大小写转换-键盘…

英文字母大小写转换

从键盘输入一个大写英文字母,将其转换味小写字母后,再显示到屏幕上(显示字符后要输出一个换行) 输入格式要求:提示信息:"Press a key and then press Enter:" 程序运行实例如下: P…

Java 字符串中的大小写字母转换

Java 实现字符串中字母大小写转换函数 实现思路:将字符串中的每个字符取出,判断该字符是不是大写字母,如果是的话则该字符32(ASCII码)并进行强制转换,转换为char,然后在通过字符串的合并操作进…

大写字母转换成小写字母

大写字母转换成小写字母 大写字母转换成小写字母1.示例:2. 解题思路3. 代码展示及分析3.1 ASCII码操作字符串转换大小写3.2 位运算 4. 运行结果 大写字母转换成小写字母 题目: 实现函数 ToLowerCase(),该函数接收一个字符串参数 str&#xf…

C++ | 大小写字母转换

1.题目描述 实现字母的大小写转换。多组输入输出。 输入描述: 多组输入&#xff0c;每一行输入大写字母。 输出描述: 针对每组输入输出对应的小写字母。 答案如下&#xff1a; #include<iostream> using namespace std;int main(){ //----------------------------…

Java-大小写字母转换

题目&#xff1a;输入一段字符&#xff0c;包含大写字母或者小写字母&#xff0c;输出对应的大写或者小写转换&#xff0c;数字不管 代码实现&#xff1a; import java.util.Scanner;public class ZimuChange {public static void main(String[] args) {System.out.println(&qu…