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

专门做二手书网站或app五 网站开发总体进度安排

专门做二手书网站或app,五 网站开发总体进度安排,wordpress 标签 seo,做网站私活多少钱目录 📦一、结构体对齐规则(🎯让内存排列更有序) 1. 第一个成员的起始位置(🚪从 0 开始的旅程) 2. 其他成员的对齐方式(📏按规则排列的队伍) 3. 结构体的…

目录

📦一、结构体对齐规则(🎯让内存排列更有序)

1. 第一个成员的起始位置(🚪从 0 开始的旅程)

2. 其他成员的对齐方式(📏按规则排列的队伍)

3. 结构体的总大小(📦整体的容量)

4. 嵌套结构体的对齐(🪆套娃的排列)

二、修改默认对齐数(🔧调整内存布局的工具)

#pragma pack 指令(⚙️灵活调整的扳手)

意义(📈平衡内存与性能)

三、offsetof 宏(了解即可)

功能与用法(🔍精准测量的工具)

四、结构体传参优化(🚀提升性能的关键)

值传递 VS 地址传递(📊对比)

详细解释与示例

值传递(📦完整复制)

地址传递(📧传递指针)

注意事项

五、结构体对齐实战案例

案例 1:计算结构体大小(📏精确计算内存占用)

案例 2:优化成员顺序(💡提高内存利用率的技巧)

六、对齐规则总结(📝回顾)

七、避坑指南

1. 误以为内存连续存放(❌错误理解)

2. 混用不同对齐数的编译器(❌兼容性问题)

3. 忘记释放动态分配的结构体(❌内存泄漏风险)

八、记忆口诀


📦一、结构体对齐规则(🎯让内存排列更有序)

1. 第一个成员的起始位置(🚪从 0 开始的旅程)

  • 结构体的第一个成员总是放在结构体变量偏移量为 0 的地址处存放。这就好比是一个装满东西的盒子,第一个物品总是放在盒子的最开头位置。

2. 其他成员的对齐方式(📏按规则排列的队伍)

  • 其他成员要对齐到某个对齐数的整数倍处。这个对齐数是成员的大小和默认对齐数的较小值。在 VS 编译器中,默认对齐数通常为 8。
  • 例如,对于以下结构体:

    struct S1 {char c1;  // 1字节,对齐数为1,从偏移量0开始存放int i;    // 4字节,对齐数为4,从偏移量4开始存放(因为4是4和8的较小值,且要对齐到4的整数倍)char c2;  // 1字节,对齐数为1,从偏移量8开始存放
    };
    // 总大小为12字节(最大对齐数4的倍数)
    

    这里的int类型成员i不能紧接着char类型成员c1存放,而是要跳过 3 个字节,从偏移量 4 开始存放,以满足对齐要求。

3. 结构体的总大小(📦整体的容量)

  • 结构体的总大小必须是结构体所有成员的对齐数中最大的那个对齐数的整数倍。
  • 例如,对于上面的struct S1,最大对齐数是 4,所以总大小为 12 字节,是 4 的整数倍。

4. 嵌套结构体的对齐(🪆套娃的排列)

  • 如果结构体中嵌套了其他结构体,嵌套的结构体要对齐到自己的最大对齐数的整数倍处。结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
  • 例如:

    struct Inner {int i;    // 4字节,对齐数为4char c;   // 1字节,对齐数为1
    };  // 总大小为8字节(最大对齐数4的倍数)struct Outer {char c;   // 1字节,对齐数为1,从偏移量0开始存放struct Inner in;  // 嵌套结构体,对齐数为4,从偏移量4开始存放
    };
    // 总大小为12字节(最大对齐数4的倍数)
    

    这里的struct Inner作为struct Outer的成员,要对齐到它自己的最大对齐数 4 的整数倍处,即偏移量 4。

二、修改默认对齐数(🔧调整内存布局的工具)

#pragma pack 指令(⚙️灵活调整的扳手)

  • 通过#pragma这个预处理指令,我们可以改变默认对齐数。
  • 语法格式为:

    #pragma pack(n)  // 设置默认对齐数为n
    struct S { ... };
    #pragma pack()   // 取消设置的默认对齐数,还原默认
    
  • 例如,当我们希望按 1 字节对齐时,可以这样写:

    #pragma pack(1)  // 按1字节对齐(取消对齐)
    struct S4 {char c;     // 1字节,从偏移量0开始存放int i;      // 4字节,从偏移量1开始存放(因为按1字节对齐,不再有对齐限制)
    };  // 总大小为5字节(无填充)
    #pragma pack()
    

    这里通过#pragma pack(1)将默认对齐数设置为 1,使得结构体成员不再受默认对齐规则的限制,从而减少了内存占用。
  • 但需要注意的是,这样可能会降低访问速度,因为 CPU 在读取数据时可能需要更多的操作来对齐数据。

意义(📈平衡内存与性能)

  • 结构在对齐方式不合适的时候,我们可以自己更改默认对齐数。这样做的意义在于,我们可以根据具体的需求来平衡内存占用和访问性能。
  • 当我们希望减少内存占用时,可以减小默认对齐数,例如设置为 1,这样可以避免内存空洞的产生,但可能会导致访问速度变慢。
  • 而当我们更注重性能时,可以适当增加默认对齐数,例如设置为 8 或 16,这样虽然会浪费一些内存,但可以提高 CPU 读取数据的效率。

三、offsetof 宏(了解即可)

功能与用法(🔍精准测量的工具)

  • offsetof是一个宏,用于计算结构体中某个成员相对于起始位置的偏移量。
  • 需要包含头文件stddef.h
  • 语法格式为:offsetof(type, member),其中type是结构体类型,member是结构体成员名。
  • 例如:

    struct S5 {char c;     // 偏移量0int i;      // 偏移量4double d;   // 偏移量8
    };printf("%zu\n", offsetof(struct S5, c));  // 输出0
    printf("%zu\n", offsetof(struct S5, i));  // 输出4
    printf("%zu\n", offsetof(struct S5, d));  // 输出8
    

    通过offsetof宏,我们可以准确地获取结构体中每个成员相对于起始位置的偏移量,这在一些需要精确控制内存布局的场景中非常有用。

四、结构体传参优化(🚀提升性能的关键)

值传递 VS 地址传递(📊对比)

传递方式优点缺点适用场景
值传递安全(不修改原数据)复制大量数据(慢)小结构体(如 Point)
地址传递高效(只传指针)可能修改原数据大结构体(如数组)

详细解释与示例

值传递(📦完整复制)
  • 值传递是将结构体对象作为参数直接传递给函数。在这种方式下,函数会接收结构体的一个副本,对副本的修改不会影响原结构体。
  • 例如:

    struct Point {int x;int y;
    };void printPoint(struct Point p) {printf("(%d, %d)\n", p.x, p.y);
    }struct Point p1 = {1, 2};
    printPoint(p1);  // 传递结构体p1的副本
    

    这里printPoint函数接收的是p1的副本,对副本的任何修改都不会影响p1本身。
地址传递(📧传递指针)
  • 地址传递是将结构体对象的地址作为参数传递给函数。在这种方式下,函数可以直接访问和修改原结构体的数据。
  • 例如:

    struct BigStruct {int data[1000];  // 4000字节char buf[100];   // 100字节
    };void printByPointer(const struct BigStruct *s) {printf("%d\n", s->data[0]);  // 用->访问成员
    }struct BigStruct s1;
    printByPointer(&s1);  // 传递结构体s1的地址
    

    这里printByPointer函数接收的是struct BigStruct类型的指针,通过指针可以直接访问和修改struct BigStruct对象的数据。

注意事项

  • 函数传参时,参数是需要压栈的,这会有时间和空间上的系统开销。如果传递的结构体对象过大,系统开销会过大,导致性能下降。
  • 因此,对于大结构体,建议使用地址传递的方式,这样可以提高效率。同时,如果不希望函数修改原结构体的数据,可以在参数前加上const关键字。

五、结构体对齐实战案例

案例 1:计算结构体大小(📏精确计算内存占用)

  • 计算以下结构体的大小:

    struct A {char a;     // 1字节,对齐数为1,从偏移量0开始存放int b;      // 4字节,对齐数为4,从偏移量4开始存放(跳过1 - 3字节)short c;    // 2字节,对齐数为2,从偏移量8开始存放
    };
    // 总大小为12字节(最大对齐数4的倍数)
    

    这里需要注意的是,int类型成员b的对齐数为 4,所以它要从偏移量 4 开始存放,即使前面有 3 个字节的空闲空间也不能占用。

案例 2:优化成员顺序(💡提高内存利用率的技巧)

  • 考虑以下两个结构体:

    // ❌ 低效布局(总大小12)
    struct Bad {char a;     // 1字节,对齐数为1,从偏移量0开始存放int b;      // 4字节,对齐数为4,从偏移量4开始存放char c;     // 1字节,对齐数为1,从偏移量8开始存放
    };// ✅ 高效布局(总大小8)
    struct Good {char a, c;  // 1 + 1字节,对齐数为1,从偏移量0开始存放int b;      // 4字节,对齐数为4,从偏移量4开始存放
    };
    

    可以看到,通过调整结构体成员的顺序,将较小的成员放在一起,可以减少内存空洞的产生,从而提高内存利用率。

六、对齐规则总结(📝回顾)

规则核心要点示例说明
偏移量规则第一个成员偏移 0,其他成员对齐到对齐数的整数倍charint跳过 3 字节
总大小规则总大小为最大对齐数的整数倍3 成员可能占 8/12/16 字节
嵌套规则嵌套结构体对齐到其最大对齐数的整数倍嵌套结构体从 4/8/16 开始
修改对齐数#pragma pack(n)改变默认对齐数pack(1)取消对齐
offsetof 宏计算成员偏移量(字节)offsetof(struct S, i)返回 4

七、避坑指南

1. 误以为内存连续存放(❌错误理解)

  • 新手常犯的错误是误以为结构体成员在内存中是连续存放的,而不考虑对齐规则。
  • 例如:

    struct Error {char c;     // 偏移量0int i;      // 偏移量4(不是1!)
    };
    // ❌ 错误:&c和&i相差4字节,不是1
    

    这里char类型成员cint类型成员i之间有 3 个字节的填充,以满足int类型的对齐要求。

2. 混用不同对齐数的编译器(❌兼容性问题)

  • 不同的编译器可能有不同的默认对齐数,例如 VS 编译器默认对齐数为 8,而 GCC 编译器默认对齐数为 4。如果在不同编译器之间混用结构体定义,可能会导致结构体大小不同,从而引发错误。
  • 解决方案是在代码中使用#pragma pack指令来强制统一对齐数,以确保结构体在不同编译器下的一致性。

3. 忘记释放动态分配的结构体(❌内存泄漏风险)

  • 如果在程序中动态分配了结构体内存,例如使用malloc函数,一定要记得在使用完后释放内存,否则会导致内存泄漏。
  • 例如:

    struct S *p = malloc(sizeof(struct S));
    // ❌ 错误:用完后必须free(p)
    

    这里如果忘记调用free(p),则分配的内存将永远无法释放,导致内存泄漏。

八、记忆口诀

结构体对齐像排队,
成员大小是关键;
偏移对齐整数倍,
总大小是最大倍数;
嵌套结构体单独算,
修改对齐用pack;
传参要用指针带,
内存效率提上来!

文章转载自:

http://sC3k2ToT.kxryg.cn
http://Z7VD2PDe.kxryg.cn
http://3ZOz0LEK.kxryg.cn
http://b6VlPfQc.kxryg.cn
http://3zgkWClO.kxryg.cn
http://OGdzQt7Y.kxryg.cn
http://3913GSuZ.kxryg.cn
http://mOh9QsjJ.kxryg.cn
http://FbhaZ2v5.kxryg.cn
http://sI01wFqL.kxryg.cn
http://7G8qRlRt.kxryg.cn
http://2H2ESSy9.kxryg.cn
http://1SM53jCH.kxryg.cn
http://kBFuQI3p.kxryg.cn
http://iaU5MMFT.kxryg.cn
http://YBH0rS5s.kxryg.cn
http://PtlBJCxY.kxryg.cn
http://bpgjcA7Q.kxryg.cn
http://P76KDgGV.kxryg.cn
http://v9d7k6xO.kxryg.cn
http://HtQ6ukk5.kxryg.cn
http://xy3isrWS.kxryg.cn
http://3Ky2J17K.kxryg.cn
http://qbtsNQCZ.kxryg.cn
http://VOz4Nv45.kxryg.cn
http://koBi0G2m.kxryg.cn
http://maDXONg4.kxryg.cn
http://Srbh0XIP.kxryg.cn
http://umi12S0W.kxryg.cn
http://RE3YebqO.kxryg.cn
http://www.dtcms.com/wzjs/774760.html

相关文章:

  • 网站的设计方法有哪些市场营销策略名词解释
  • 成都电子商城网站开发wordpress登录页面修改
  • 网站手机版建设网站域名备案在阿里云怎么做
  • 中文的网站做不成二维码wordpress迁移typecho
  • 公司和公司网站的关系wordpress局部内容
  • 瑞金网站建设推广做网站大概需要多少费用
  • 网站制作如皋定制微信怎么做
  • 英德市住房城乡建设网站上海手机网站哪家最好
  • 国内做的比较好的旅游网站建设黑彩网站需要什么
  • 一个备案号可以放几个网站平面设计作品集欣赏
  • cnzz统计代码放在网站南海网站建设哪家好
  • 网站建设放在什么科目电子商务网站开发目标
  • 中国建设企业银行网站首页wordpress修改个人头像
  • 张家界网站建设企业wordpress 在线留言
  • 网站分类 维护济南最新消息今天
  • 新增网站惠州市建设局网站
  • 深圳做网站排名公司哪家好北京网站建设销售招聘
  • 网站建设技术规范网站前置审批在哪里办
  • 淄博网站建设给力臻动传媒移动网站开发技术
  • 创造你魔法官方网站起做欢的事温州手机网站开发
  • 微信官方网站是什么地图网站怎么做的
  • 网站建设费是业务宣传费吗wordpress模仿知乎
  • 青岛市建设局网站停工seo公司网站推广
  • 3d网站开发成本企业关键词排名优化网址
  • 研发项目备案在哪个网站做简单php企业网站源码
  • 广州网页设计师工资一般多少上海搜索引擎优化seo
  • 铭讯网站建设上海网站设计的公司
  • 网站分站系陕西省建设造价协会网站
  • 求购做网站app平台开发需要的资源与团队
  • ps扩展插件网站外贸推广公司哪家好