打印
[DemoCode下载]

结构体-进阶小技巧

[复制链接]
179|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cemaj|  楼主 | 2025-2-20 02:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
结构体匿名结构体类型

在声明结构体的时候,可以不完全声明
比如:

struct{    int a;    char b;    float c;}x;

只能使用一次
只能定义全局变量
不建议使用

结构的自引用

在结构中包含一个类型为该结构本身的成员是不行的
例如:

struct Node{    int data;    struc Node next;}

这样会无限创建结构空间,类似于递归的死循环
**自引用只能用自己的指针 **
例如:

struct Node{    int data;    struct Node*next;}结构体内存对齐结构体对齐规则

注意 嵌套结构体的结构体,其中嵌套的结构体不是按自身的大小进行对齐数比较的,而是自身元素中的最大对齐数来和默认对齐数进行比较,最后被嵌套的结构体的大小是其各元素的最大对齐数的倍数

实例演示:

此结构体一共占16个字节

  • 第一个成员在偏移量为0的地址,c1是第一个地址,并且char类型占一个字节,c1占1个字节与VS默认对齐数取小,c1的对齐数为1
  • i占4个字节与VS默认对齐数取小,i的对齐数为4,占偏移量为4的倍数的地址,占据地址4到7(int类型占4个字节)
  • d占8个字节与VS默认对齐数取小,d对齐数为8,占偏移量为8的倍数的地址,占据地址8到15(double类型占8个字节)
  • 所有成员中的最大对齐数为8(c1是1,i是4,d是8),所以结构体一共占8的倍数个字节,0,4到7,8到15一共16个字节,刚好是8的倍数个字节(如果不是则需要浪费空间来补足最大对齐数的倍数)
为什么存在内存对齐?
  • 平台原因(移植原因):不是所以的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常
  • 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问
    总体来说: 结构体的内存对齐是拿空间来换取时间的做法
满足对齐又要节省空间

让占用空间小的成员尽量集中在一起

struct s1{    char c1;    int i;    char c2;};struct s2{    char c1;    char c2;    int i;}

s1和s2类型的成员一模一样,但是s1和s2所占空间的大小有了一些区别

修改默认对齐数

返回当前成员名偏移量

宏offsetof(类型,成员名)
需头文件<stddef.h>

结构体传参

/-
优先使用地址传参,这样可以不用再创建一个相同大小的空间来存储参数
/-

位段位段的声明

位段的声明和结构体是类似的,有两个不同:

  • 位段的成员必须是有/无符号int或有/无符号char
  • 位段的成员名后边有一个冒号和一个数
位段的内存分配

位段的跨平台问题



使用特权

评论回复
沙发
天灵灵地灵灵| | 2025-2-20 09:17 | 只看该作者
结构体的位好像只能连续,不能交叉。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

3870

帖子

2

粉丝