IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【C语言】自定义类型——结构体与内存对齐 -> 正文阅读

[数据结构与算法]【C语言】自定义类型——结构体与内存对齐

一、什么是结构体

与int,double等内置类型不同,结构体是C语言为用户提供的一种进行多种类型定义的集合体。一言蔽之:结构体是可以一个存放多种类型的对象的集合。
例子:

int a;
double b;
long c;
//内置类型变量一旦创建,该变量将实例化在操作空间里,如果需要对其进行值的操作直接进行赋值即可
struct tag
{
    int aa;
    double bb;
    long cc;
};
//结构体将一些我们需要即将进行操作的内置或非内置类型“打包”在一起

值得一提的是,结构体类型作为一种自定义类型并不会在创建时就完成相关的值的初始化操作,而是首先创建一个“模板”,如果需要使用该结构体类型时则需要将该结构体作为变量类型进行创建结构体变量,比如需要使用tag类型的结构体创建变量时

struct tag t1;//创建一个上述声明的结构体变量不赋值,此时结构体被实例化,t1变量类型为tag类型,t1中包含 aa ,bb ,cc三种类型的变量

struct tag t2 = {1, 2.0, 255};//创建一个结构体变量t2同时赋值初始化

//在C99和C11也可以使用初始化器的方式对结构体变量进行赋值
struct tag t1 ={ .aa = 1, 
                 .bb = 2.0, 
                 .cc = 255};

结构体内的变量的声明可以是任何类型,如:数组、指针、其他结构体变量等等。

struct Node
{
     char name[15];
     int age;
     struct* Node next;
}typedef Node;
//typedef重定义struct Node为Node,即进行定义结构体变量时使用Node作为关键字即可

Node n1 = {"Li Ming",
            15,
            NULL};//创建结构体变量n1并进行初始化

二、结构体内存对齐

上述描述中以及了解到结构体是一种“超级数组”,结构体内可以存储各种类型的变量。但是问题也接踵而至,一个内置类型如int类型我们通过sizeof操作可以知道int类型的大小为4个字节,double类型为8个字节。那么一个结构体类型所占的存储空间又是多少呢?有人突发妙想,认为只需将我们认识的类型进行堆砌即可。但下述例子有力的回应了这种观点的错误。

struct tag1
{
    int aa;
    double bb;
    long cc;
};
struct tag2
{
    double bb;
    int aa;
    long cc;
};

struct tag1struct tag2内部所声明的变量类型完全相同,只有内部顺序不同,依照上述观点,你可以得出tag1与tag2所占空间均为4+8+8=20字节的结论。但是我们分别使用sizeof对tag1和tag2进行操作就会发现:tag1所占空间为24个字节(编译器对齐数为8)、tag2所占空间为64个字节(编译器对齐数为8)说明上述观点是存在错误的。这是因为由于编译器移植等性能原因,结构体类型的存储方式并不能完全依照内置类型方式进行存储。存在结构体内存对齐的存储方式以便代码高效运行。

1、 结构体内存对齐规则

  • 结构体的第一个成员永远放在结构体起始位置偏移量为0的位置
  • 从第二个成员开始,结构体成员总是放在对齐数的整数倍处(对齐数=编译器默认对齐数和自身大小的较小值)
  • 结构体的总大小必须是各个成员的对齐数中最大那个对齐数的整数倍
  • 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍处

那么在上述的tag1中计算规则应为4+(4)+8+8=24,其中括号中表示对齐占位字节

tag2中计算规则应为8+4+(40)+8+(4)=64,
可以看出即使结构体存放相同的变量类型,顺序不同,所占空间将会有显著差异
所以,一般情况下,我们在定义结构体时应使用占位空间从小到大的形式对变量进行定义。

2、为什么存在内存对齐?

  1. 平台原因:不是所有硬件平台上都能访问地址上的任意数据;某些硬件只能特定地读取数据
  2. 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存访问仅需要一次。

这就是结构体与它的内存对齐,希望这篇文章对你有所帮助!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:48:16  更:2022-03-08 22:48:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:48:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码