64.【C语言】再议结构体(下)

本文衔接第63篇63.【C语言】再议结构体(上)

目录

目录

6.复习

7.修改默认对齐数

8.结构体传参

01.传递非指针参数

02.传递指针参数(传递地址)

03.对比

9.结构体实现位段

01.位段的定义

02.格式

03.例题

答案速查

分析

10.位段跨平台问题

11.位段的应用

12.其他注意事项



6.复习

20.【C语言】初识结构体(重要)

48.【C语言】结构体补充

63.【C语言】再议结构体(上)

7.修改默认对齐数

加一条预处理指令

#pragma pack(对齐数)
struct 结构体标签{成员列表;}变量列表(全局变量);//变量列表可以不写,但;必须有!!!

 在#pragma pack(对齐数)后紧跟着结构体就能指定该结构体的对齐数

建议给1,2的次方数:2,4,8

#include <stdio.h>
#pragma pack(1)
struct s1
{char a;char b;int c;
};
#pragma pack()//恢复默认对齐数int main()
{printf("%zd", sizeof(struct s1));return 0;
}

打印结果为6

8.结构体传参

01.传递非指针参数

#include <stdio.h>
struct s
{int data[1000];int num;
};void sim_print(struct s ss)//结构体传参
{int i = 0; for (i = 0; i < 5; i++){printf("%d ",ss.data[i]);}printf("\nnum = %d\n", ss.num);
}int main()
{struct s s = { { 1, 2, 3, 4, 5 } , 100 }; sim_print(s);return 0;
}

 649fedba905547ce98c30e0799df9aa3.png

f592253b4fb1450b9a35f9439c373d9e.png

02.传递指针参数(传递地址)

#include <stdio.h>
struct s
{int data[1000];int num;
};//结构体传参,*ps表明传递的是指针
void sim_print(struct s *ps)
{int i = 0; for (i = 0; i < 5; i++){printf("%d ",ps->data[i]);}printf("\nnum = %d\n", ps->num);
}int main()
{struct s s = { { 1, 2, 3, 4, 5 } , 100 }; sim_print(&s);//传的是地址return 0;
}

注:结构体成员变量->成员名是结构体特有的写法

03.对比

当结构体成员变量占用较大的内存时, 因为参数要压栈,所以传递指针参数比传递非指针参数要节省空间,传递指针参数不会另外开辟额外的空间

9.结构体实现位段

01.位段的定义

摘自百度百科:

C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”(bit field),利用位段能够用较少的位数存储数据

02.格式

类型 成员变量:数字;

如: int a:5;

03.例题

求下列代码的执行后位段在内存中的数据(在VS2022中测试)

struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};int main()
{struct S s = { 0 };//注意区分大小写s.a = 10;s.b = 12;s.c = 3;s.d = 4;return 0;
}

答案速查

位段在内存中的数据:62 03 04

分析

因为 以位为单位来指定其成员所占内存长度

前置知识:位段的内存分配

2条规则,1条提醒

1.位段的成员可以是int,unsigned int,signed int,char等类型

2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的

提醒:位段涉及很多不确定因素,位段不跨平台,注重可移植的程序应该避免使用位段(本文后面会单独讲)

位段的内存分配

1.数据的存储顺序由是编译器而定(C标准没有规定)

2.每次向CPU申请1byte,如果不够则继续申请1byte

3.是否浪费空间取决于编译器(C标准没有规定)

解析

未存储数据时:

8b54a2c5b70741d3a0b31291363bed7c.png

分类讨论:

若按浪费空间处理

由低地址向高地址存储,设数据的二进制的存储顺序为从右向左(VS2022满足此情况)

十进制10==二进制1010 十进制12==二进制1100 十进制3==二进制11 十进制4==二进制100

    char a : 3;-->a占3位,1010会被截断为3位010存储
    char b : 4;-->b占4位,恰好可以存储1100
    char c : 5;-->c占5位,11占2位,因此补前导零存储为00011
    char d : 4;-->d占4位,100占3位,因此补前导零存储为0100

bca644ba52134c04bde9d4f35623ab84.png

 按十六进制拆分:0110 0010 0000 0011 0000 0100-->62 03 04

位段的空间以4个字节(int)或者1个字节(char)的方式来开辟的,a,b,c,d的类型全为char,因此不用改动为62 03 04 00

验证

VS2022+x64+debug环境下,VS2022调试,F11逐语句

打开内存窗口,输入&s(小写的s)

1c00e7ec857d4297977fbc51bd1b0aa2.pngde85388a6fd34fba86f07a8793c38583.png

b340dfd98b364e48a8e49e951e5cce55.png

03d67f85d9544c539904305d7925596c.png

176711e990a04735b45453832a1434b8.png

10.位段跨平台问题

1.int 位段被当成有符号数还是无符号数是不确定的(即最高位为1还是0不确定)

2.位段中最大位的数目不能确定

例如:int a : 34;

a为34位,在16位和32位机器均不能存储,但在64位机器可以

3.位段中的成员在内存中的存储顺序为从左向右还是从右向左,C标准尚未定义

4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,不确定

因此跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在

11.位段的应用

下图是网络协议中IP数据报的格式,可以看到其中很多的属性只需要几个bit位就能描述

这里使用位段能节省了空间,这样网络传输的数据报大小也会较小一些,对网络的畅通是有帮助的。

12.其他注意事项

位段的几个成员共有同一个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的(内存中每个字节分配一个地址,一个字节内部的bit位是没有地址的)
所以不能对位段的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在一个变量中,然后赋值给位段的成员

int a=0;
scanf("%d",&a);
s.a = a;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scrapy 爬取微博(五)【最新超详细解析】: 爬取微博文章

1 读取配置参数 爬取微博文章首先需要读取settings.py中的设置的配置变量&#xff0c;然后编写爬虫&#xff0c;读取的配置变量主要有爬取的关键词、时间范围、爬取区域等。 class WeiboSearchSpider(scrapy.Spider):name weibo_searchallowed_domains [weibo.com]settings…

完成UI界面的绘制

绘制UI 接上文&#xff0c;在Order90Canvas下创建Image子物体&#xff0c;图片资源ui_fish_lv1&#xff0c;设置锚点&#xff08;CountdownPanelImg同理&#xff09;&#xff0c;命名为LvPanelImg,创建Text子物体&#xff0c;边框宽高各50&#xff0c; &#xff0c;重名为LvT…

影刀---如何进行自动化操作

本文不是广告&#xff0c;没有人给我宣传费&#xff0c;只是单纯的觉得这个软件很好用 感谢大家的多多支持哦 本文 1.基本概念与操作&#xff08;非标准下拉框和上传下载&#xff09;非标准对话框的操作上传对话框、下载的对话框、提示的对话框 2.综合案例3.找不到元素怎么办&a…

css 中 ~ 符号、text-indent、ellipsis、ellipsis-2、text-overflow: ellipsis、::before的使用

1、~的使用直接看代码 <script setup> </script><template><div class"container"><p><a href"javascript:;">纪检委</a><a href"javascript:;">中介为</a><a href"javascript:…

架构师:消息队列的技术指南

1、简述 消息队列(Message Queue, MQ)是一种异步通信机制,允许系统的各个组件通过消息在彼此之间进行通信。消息队列通过解耦系统组件、缓冲高峰期请求和提高系统的可扩展性,成为分布式系统中不可或缺的一部分。 2、工作原理 消息队列的基本工作原理是生产者将消息发布到…

python爬虫案例——抓取链家租房信息(8)

文章目录 1、任务目标2、分析网页3、编写代码1、任务目标 目标站点:链家租房版块(https://bj.lianjia.com/zufang/) 要求:抓取该链接下前5页所有的租房信息,包括:标题、详情信息、详情链接、价格 如: 2、分析网页 用浏览器打开链接,按F12或右键检查,进入开发者模式;因…

Axure-本地发布,局域网内用户访问

目录 前言内容一. 选择Axure发布路径&#xff0c;进行相应配置二.添加IIS服务配置&#xff08;不在这里赘述&#xff01;&#xff09;三&#xff1a;添加IIS配置&#xff0c;创建网站四.添加安全策略&#xff1a;实践&#xff1a; 前言 最近加入了公司的积分系统&#xff0c;由…

Qt网络编程——QUdpSocket

文章目录 Qt网络编程QUdpSocketUdp回显服务器Udp客户端 Qt网络编程 网络编程本质上是写应用层代码&#xff0c;需要传输层提供支持。 而传输层最核心的协议就是UDP和TCP&#xff0c;这两个协议有较大差别&#xff0c;所以Qt提供了两套API。 要是有Qt网络编程的API&#xff0…

【CSS Tricks】css动画详解

目录 引言一、动画关键帧序列二、动画各属性拆解1. animation-name2. animation-duration3. animation-delay3.1 设置delay为正值3.2 设置delay为负值 4. animation-direction5. animation-iteration-count6. animation-fill-mode7. animation-play-state8. animation-timing-f…

Kubernetes云原生存储解决方案之 Rook Ceph实践探究

Kubernetes云原生存储解决方案之 Rook Ceph实践探究 除了手动部署独立的 Ceph 集群并配置与Kubernetes进行对接外&#xff0c;Rook Ceph 支持直接在 Kubernetes 集群上部署 Ceph 集群。 通过Rook Ceph云原生存储编排平台&#xff0c;使得 Kubernetes 集群中启用高可用的 Ceph…

RabbitMQ常用管理命令及管理后台

RabbitMQ管理命令 1、用户管理1.1、新增一个用户1.2、查看当前用户列表1.3、设置用户角色1.4、设置用户权限1.5、查看用户权限 2、RabbitMQ的web管理后台2.1、查看rabbitmq 的插件列表2.2、启用插件2.3、禁用插件2.4、访问RabbitMQ的web后台2.4、通过web页面新建虚拟主机 ./rab…

【计算机网络】详解HTTP请求和响应格式常见请求方法Header报头响应报文状态码URL

一、HTTP协议的定义 在互联网世界中&#xff0c;HTTP &#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一个至关重要的协议。它定义了客户端&#xff08;如浏览器&#xff09;与服务器之间如何通信&#xff0c;以交换或传输超文本&#xff08…

如何选择合适的跨境网络专线?

选择合适的跨境网络专线对于保障企业的国际业务顺畅运行至关重要。以下是一些选择跨境网络专线时可以参考的关键点&#xff1a; 服务商的信誉和经验&#xff1a;首先考察服务商的市场声誉和行业经验。一个好的服务商应该拥有良好的客户评价和成功案例&#xff0c;这表明他们有能…

【4.5】图搜索算法-BFS和DFS求岛屿的最大面积

一、题目 给定一个包含了一些 0 和 1 的非空二维数组 grid 。一个岛屿是由一些相邻的 1 (代表土地)构成的组合&#xff0c; 这里的「相邻」要求两个1必须在水 平或者竖直方向上相邻 。你可以假设 grid 的四个边缘都被0&#xff08;代表水&#xff09;包围着。 找到给定的二维…

4.数据结构与算法-线性表的顺序表示和实现

2.1 线性表的定义和特点 线性表例子 线性表的逻辑特征 2.2 案例引入 案例2.1 案例2.1&#xff1a;一元多项式的运算 案例2.2&#xff1a;系数多项式的运算 用时间换取空间--线性数组相对链式访问速度快 但这种方法链式更节省空间&#xff0c;所以用时间换取空间 案例2.3&…

Hbase要点简记

Hbase要点简记 Hbase1、底层架构2、表逻辑结构 Hbase HBase是一个分布式的、列式的、实时查询的、非关系型数据库&#xff0c;可以处理PB级别的数据&#xff0c;吞吐量可以到的百万查询/每秒。主要应用于接口等实时数据应用需求&#xff0c;针对具体需求&#xff0c;设计高效率…

Arm Linux 交叉编译openssl 1.1.1

一、openssl 源码下载 OpenSSL的官方网站或源代码仓库下载最新或指定版本的OpenSSL源代码。 官网地址&#xff1a; https://openssl-library.org/source/index.html 旧版本下载&#xff1a; https://openssl-library.org/source/old/index.html 这里以 1.1.1 为例 国内git…

plt.bar函数介绍及实战

目录 plt.bar() 函数实战 plt.bar() 函数 plt.bar() 函数是 Matplotlib 中用于创建柱状图的函数。它用于在图形中绘制一个或多个柱状图&#xff0c;通常用于展示类别型数据的数量或大小的比较。 基本语法&#xff1a; plt.bar(x, height, width0.8, bottomNone, aligncenter…

归并排序,外排序,计数排序(非比较排序)

归并排序&#xff1a;&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有序…

大模型(LLM) 是仅仅比 模型(Model) 更大吗?

我们日常经常提到模型 model&#xff0c;大模型LLM&#xff0c;大家都知道这两者之间的区别和联系吗&#xff1f; 只是如下图这样&#xff0c;大小的区别吗&#xff1f;下面我们对模型model和大模型LLM进行解释和描述 什么是模型&#xff1f; 模型是机器学习中一个核心概念&a…