课外闲谈4.对齐数的概念

简介: 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字符;

什么地方要用到对齐数的概念呢?


只要涉及到多个数据的内存的存储方面,一般是都要讲对齐这个概念的,但是在目前为止,对齐这个概念注意凸显在结构体中。因为数组中都是同种类型的数据,所以并不会浪费空间。但是结构体中存储的是不同类型的数据,难免会浪费一些空间。


C语言之内存对齐数_微风-CSDN博客_c语言内存对齐

https://blog.csdn.net/qq_34328833/article/details/51352663?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163993041416780357221063%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163993041416780357221063&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-51352663.pc_search_result_cache&utm_term=%E5%AF%B9%E9%BD%90%E6%95%B0&spm=1018.2226.3001.4187

 问题一:为什仫要内存对齐?


   我们知道的是计算机中最小的存储单位是字节(一个字节是八个比特位),当我们查找数据的时候可以一个字节一个字节的查找,但是这种查找方式存在缺陷:查找速度慢。如果不存在内存对齐,在实例三中,我们首先为结构体变量c分配一个字节,然后紧着我们为结构体变量c2分配一个字节,在最后我们为结构体整形变量i分配四个字节;如果我们一个字节一个字节查找元素的话,找c和c2当然很容易了,可是找i呢?我们知道内存为整形变量i分配了4个字节,我们要访问完整的i我们需要找到变量c2之后的四块存储空间,和我们刚开始定义的一样我们是一个字节一个字节找,此时指针需要移动三次才可以找到全部整形变量i的所有字节。是不是觉得很麻烦呢?如果有了内存对齐呢?我们可以四个字节四个字节的找,是不是就提高了我们查找的速率呢?那是肯定的啦!所谓的内存对齐就是牺牲了部分空间来换取效率的方法。


     问题二:内存对齐有哪些规则?


       1).结构体变量的首地址能够被其最宽基本类型成员的大小所整除,结构体的第一个成员永远放在零偏移处;

       2).结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字符;

       3). 结构体的总大小为结构体最宽基本类型成员大小和编译器缺省対界条件大小中比较小得那个值的整数倍,如有需要编译器会在最后一个成员之后加上填充字节;


      4).在这里我们是可以修改默认对齐数的,一般我们用 #progma pack(n)这个语句来设置默认对齐数, 在这个我设置的默认对齐数是n,读者可根据自己的需要自行设置对齐数;用#progma pack()来取消设置对齐数, 换句话说就是我们可以自己修改内存中的默认对齐数;


     通过上述几个规则大家是不是对内存对齐有了更深的理解呢?下面我就来画图理解上述三个类似的范例:


    20160513224117014.png


C语言之内存对齐数_微风-CSDN博客_c语言内存对齐

https://blog.csdn.net/qq_34328833/article/details/51352663?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163993041416780357221063%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163993041416780357221063&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-51352663.pc_search_result_cache&utm_term=%E5%AF%B9%E9%BD%90%E6%95%B0&spm=1018.2226.3001.4187

#pragma 这是个预处理指令,可以修改默认对齐数


这下面两个分别是改了默认对齐数和没有改的。


48d06a612b8048ed8a7c8bb374c3b53c.png

cf6b06776d554e4fa05e672e235af934.png


改完之后记得要还原。


4540b653ac5947348fe8bb7208f4d33c.png


补:


offsetof函数,返回值为偏移量


size_t offsetof(类型名,成员名)


返回值为相对于结构体头部的偏移量。

目录
打赏
0
0
0
0
6
分享
相关文章
|
9月前
|
算法编程(十六):快乐数
算法编程(十六):快乐数
88 0
|
1月前
|
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
61 24
【C语言程序设计——选择结构程序设计】判断一个数是不是5和7的倍数(头歌实践教学平台习题)【合集】
本任务要求输入一个正整数,判断其是否同时是5和7的倍数,若是输出"Yes",否则输出"No"。内容涵盖选择结构的基本概念、主要语句类型(if、if-else、switch)及条件判断逻辑,帮助理解编程中的分支执行与条件表达式。测试用例包括正数、负数及非倍数情况,确保代码逻辑严谨。通关代码示例如下: ```cpp #include "stdio.h" int main(){ int a; scanf("%d", &a); if (a <= 0){ printf(&quo
48 0
工作3年,还分不清文件大小单位关系的?就看这篇吧!
工作3年,还分不清文件大小单位关系的?就看这篇吧!
|
6月前
|
惊爆!KPM算法背后的秘密武器:一行代码揭秘字符串最小周期的终极奥义,让你秒变编程界周期大师!
【8月更文挑战第4天】字符串最小周期问题旨在找出字符串中最短重复子串的长度。KPM(实为KMP,Knuth-Morris-Pratt)算法,虽主要用于字符串匹配,但其生成的前缀函数(next数组)也可用于求解最小周期。核心思想是构建LPS数组,记录模式串中每个位置的最长相等前后缀长度。对于长度为n的字符串S,其最小周期T可通过公式ans = n - LPS[n-1]求得。通过分析周期字符串的特性,可证明该方法的有效性。提供的C++示例代码展示了如何计算给定字符串的最小周期,体现了KPM算法在解决此类问题上的高效性。
125 0
|
9月前
|
算法编程(十五):位1的个数
算法编程(十五):位1的个数
60 0
|
9月前
|
【C语言】“分⽀与循环第一章:开启创新之门,探索无尽可能性的第一篇章“2
【C语言】“分⽀与循环第一章:开启创新之门,探索无尽可能性的第一篇章“2
|
9月前
|
【C语言】“分⽀与循环第一章:开启创新之门,探索无尽可能性的第一篇章“1
【C语言】“分⽀与循环第一章:开启创新之门,探索无尽可能性的第一篇章“
工作中学到的一些小点
工作中学到的一些小点

热门文章

最新文章