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

姜堰住房和城乡建设厅网站首页成都网站建设福州

姜堰住房和城乡建设厅网站首页,成都网站建设福州,站长忽略的观点,做网站一天自定义类型(结构体、联合体、枚举) 一、结构体(一)结构体的内存对齐1、结构体内存对齐规则(1)引子(2)offsetof 宏函数(3)内存对齐原理(4&#xff…

自定义类型(结构体、联合体、枚举)

一、结构体

(一)结构体的内存对齐

1、结构体内存对齐规则

(1)引子

结构体占多少内存呢,是不是各个变量的内存之和呢,先用一段代码来验证我们的猜想吧。下面代码中,如果我们猜想正确,那么打印结果就应该是三个变量的字节数之和,答案为6.
在这里插入图片描述
在这里插入图片描述

(2)offsetof 宏函数
offsetof (type,member)   返回成员变量number距离结构体首地址的偏移量(单位是字节)

我们对结构体S的a, b, c,分别查看他们的偏移量。
在这里插入图片描述
在这里插入图片描述
根据这个结果,我们可以画出下面的内存图解。

在这里插入图片描述

(3)内存对齐原理

1、结构体的第一个成员变量对齐到和结构体首地址偏移量为0的地址处

2、其它成员变量要对齐到对齐数的整数地址处。
对齐数 = 编译器的默认对齐数该结构体成员变量的大小 中的较小值

3、结构体大小为最大对齐数的整数倍。

4、如果结构体嵌套结构体,嵌套的结构体变量要对齐到自己成员变量中最大对齐数整数倍的地址处。结构体大小就是所有成员(包含结构体中的成员)中最大对齐数的整数倍。

求下面代码的输出结果。

struct S1 {double a;char b;int c;
};struct S2 {char a;struct S1 b;double c;
};int main() {printf("%zd", sizeof(S2));return 0;
}

要求结构体S2的大小,我们首先要求结构体S1的大小,分析如下。
在这里插入图片描述
接着再求结构体S2的大小
在这里插入图片描述
分析结果为32和我们预料的一致。
在这里插入图片描述

(4)自定义默认对齐数

使用 #pragma pack(int val)可以设置默认对齐数。
例如:

 	#pragma pack(1)//将默认对齐数设置为1struct S {char c1;int n;char c2;
}#pragma pack() //重置默认对齐数

2、为什么要内存对齐

所以说不仅步骤麻烦,还消耗了内存,为什么还要内存对齐呢。用空间换时间

(1)性能原因

为了访问未对齐的数据,处理器需要访问多次,而处理对齐的数据,处理器访问次数减少。

struct S {char a;int b;
};

在32位平台中,我们一次可以访问四个字节。下面我们访问变量 b 并用内存对齐和非内存对齐来对比
内存对齐
在这里插入图片描述
**加粗样式**
非内存对齐
通过非内存对齐,发现我们起码要通过两次才能拿到 int 成员变量。
在这里插入图片描述

(2) 平台原因

不是所有平台都能访问任意地址上的任一数据。

(二)结构体实现位段

1、位段的定义

位段中的位指的是二进制位,和结构体类似,有两点不同
1、位段的类型只能是 int 、signed int、unsigned int 或者是char(整形家族),C99中引入了其它类型。

2、位段后面比较加冒号和数字,表示为该变量分配多少个比特位的空间。
如下:

struct S {int a : 2;int b : 6;int c : 4;int c : 4;
};

2、位段的储存

位段也有自己的储存方式,我们分析下面一段代码进行体会

struct S {int a : 3;int b : 4;int c : 5;int d : 4;
};int main() {printf("%d", sizeof(struct S));return 0;
}

在这里插入图片描述
注意:
位段在初始化变量时候不可以用scanf,因为&符号是以一个字节为单位,显然如果一个字节里面有多个变量的话,会引发错误。

3、位段的不可跨平台性

1、数据类型解释的不确定性:

有符号与无符号:位段中的int类型成员是否被当作有符号数还是无符号数,在不同的编译器和平台上可能存在差异。

位数限制:位段中成员的最大位数在不同的编译器和平台上可能有所不同。例如,在16位机器上,位段的最大位数可能为16,而在32位机器上可能为32。

2、内存分配方式的不确定性:

分配方向:位段成员在内存中的分配方向(从左到右或从右到左)在C语言标准中并未明确定义,这可能导致在不同的编译器和平台上出现不同的内存布局。

空间利用:当一个结构体包含多个位段成员,且后一个成员无法完全容纳在前一个成员剩余的位中时,是舍弃剩余位还是尝试利用这些位,也是不确定的。

4、位段的应用

网络协议中用来包装IP数据报(就好像外卖一样,需要填写目的地的信息),而位段进行封装就会使得包裹更加便捷。

二、枚举

(一)枚举的定义

我们可以把生活中一些事物所对应的情况一一列举处来,就是枚举。
如下,其中enum就是枚举类型,{}里的内容就是枚举常量。
在这里插入图片描述
变量中的枚举常量默认赋初始值为0 1 2 3 … 也可以自定义赋值。自定义赋值时,可以选择性赋值,没有赋值的会序列化自动赋值。

(二)枚举的优点

在这里插入图片描述
枚举的优点用以下代码可以充分体现。

enum Option
{EXIT,//0ADD,//1SUB,MUL,DIV
};void menu()
{printf("**********************************\n");printf("****** 1. add    2. sub     ******\n");printf("****** 3. mul    4. div     ******\n");printf("****** 0. exit              ******\n");printf("**********************************\n");
}int main()
{int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case SUB://break;case ADD:break;case MUL:break;case DIV:break;case EXIT:printf("退出\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}

三、联合体

(一)联合体的储存

我们直接将联合体的储存是因为他和结构体上面就一个本质差别:联合体成员公用同一块空间(所以联合也叫共用体)。
规则:
1、联合的大小至少是最大成员的大小。
2、当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
在这里插入图片描述
在这里插入图片描述

(二)联合体的应用

联合体和结构体嵌套使用,可以节省很多内存:
在这里插入图片描述
例如我们需要使用该结构体,如果前面三个公共属性必选,而特征属性非必选,我们可以设置下面的代码来减少结构体的内存:

在这里插入图片描述

四、结束语

到此这篇文章就告一段落了,小编还会继续用心对待每一篇文章,与大家一起进步,非常有幸能得到大家的支持!
在这里插入图片描述

http://www.yayakq.cn/news/522953/

相关文章:

  • 哪个网站银锭专业做银锭的企业年金辞职了怎么办
  • 排行榜哪个网站最好鞍山网站制作人才招聘
  • 如何做供求网站咸阳网站建设
  • vps 做镜像网站河源市住宅和城乡规划建设局网站
  • 网站迁移后 后台进不去济南百度提升优化
  • 网站建设调研表邢台163交友手机端
  • 潍坊网站建设推荐永久域名注册
  • 网站架设地址seo整站优化吧
  • 国外建设网站网站备案怎么改
  • 餐饮网站欣赏城乡建设工程信息网
  • 深圳建设工程项目网站2021年uc秒懂网址
  • 东营企业自助建站手机网站建设网站
  • 网站开发厦门网站关键词优化怎么做
  • 移动网站备案抖音广告怎么投放
  • 黄石规划建设局网站那个网站效果图做的好
  • 学校网站建设流程电脑编程培训学校哪家好
  • asp网站版权怎么做电影引流网站
  • 佛山网站设计讯息网络营销相关的岗位有哪些
  • 平面设计网站建设那有做网站的
  • 做市场浏览什么网站乡村旅游网站建设
  • 食品网站建设的照片网站建设项
  • 网站建设域名和空间续费快手自媒体平台
  • 四川省工程建设管理协会网站wordpress kindeditor
  • 河南省住房和城乡建设厅新网站绵阳住房和城乡建设厅官方网站
  • 搜索引擎网站排名优化方案好的建网站的书籍
  • 域名建网站seo是什么意思揉若湖南岚鸿专注
  • 专业品牌网站设计公司网站不支持下载的视频怎么下载
  • 网站名称 规则怎样在百度上发布自己的信息
  • 济源做网站怎么收费大学生html网页设计个人博客模板
  • 哪个行业最需要做网站ppt模板下载免费版软件