结构体(自定义类型)

news2024/11/17 15:33:26

1.结构体

结构体这种自定义的数据类型,让程序员可以自己创造适合的类型

结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量,可以是标量,数组,指针甚至是其他结构体

1.1.1 结构的声明

                                                                                 eg:描述一个学生:

struct  tag                                                                   struct  Stu

{                                                                                   {

      member - list;                                                                 char  name[20];

}variable - list;                                                                       int  age;

                                                                                             char  sex[5];

                                                                                      };

1.1.2 结构体变量的创建(定义)和初始化

1.2结构的特殊声明

匿名结构体类型

如果没有对结构体类型重命名,基本上只能使用一次

这个类型是没有名字的,但我们创建变量x

1.3 结构体的自引用

在结构中包含一个类型为该结构本身的成员的不可行的,因为一个结构体中再包含一个同类型的结构体变量,这样结构体变量的大小就会无穷的大,是不合理的

正确的方法:结构体里面有一个同类型的结构体指针

2.结构体内存对齐

2.1对齐规则

1.不管哪种类型的结构体类型,第一个成员都要放到偏移量为0的位置处,从0开始

1.1偏移量

      offsetof -- 宏

      计算结构体成员相较于结构体变量起始位置的偏移量

相关:

https://cplusplus.com/

2.1其他成员对齐到某个数字(对齐数)的整数倍的地址处

对齐数=编译器默认的一个对齐数与该成员变量大小的较小值

-VS中默认的值为8

-Linux中gcc没有默认对齐数,对齐数就是成员自身的大小

3.结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的整数倍

4.如果嵌套了结构体的情况,嵌套的结构体成员到自己的成员中最大对齐数的整数倍处,结构体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍

画图表示

1.

2.

3.

4.

2.2为什么存在内存对齐

1)不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取某些特定类型的数据,否则出现硬件异常

2)为了访问未对齐的内存,处理器需要做两次内存访问

而对齐的内存访问仅需一次。

假设一个处理器总是从内存中取8个字节,则地址必须是8的倍数。

如果我们能保证所有的double类型的数据的地址都对齐成8的倍数,那么就可以用一个内存操作来读或者写值了,否则,我们可能需要执行两次内存访问,因为对象可能被分别放在两个8字节内存块中

结构体的内存对齐是拿空间换取时间的做法(对齐提升访问效率)

在设计结构体的时候,我们既要满足对齐又要节省空间时则应该让占用空间小的成员尽量集中在一起

2.3 关于默认对齐数

#pragma 这个预处理指令可以改变编译器的默认对齐数,结构体在对齐方式不合适的时候,我们可以自己更改默认对齐数

3.结构体传参

结构体传参的时候,要传结构体的地址

传值调用时,形参传给实参的时候,实参要创建一份自己的空间,如果结构体比较大则需要比较大的空间,同时传过去也是需要时间的。传地址能够做到的更多

4.结构体实现位段

4.1位段是什么

位段是和结构体相关

位段中的位指的是二进制的位

                              bit位

位段的声明和结构是类似的

不同:

1)位段的成员必须是int,unsigned int,signed int

      在C99中位段成员的类型也可以选择其他类型

2)位段的成员名后面有一个冒号和一个数字

A(1)就是一个位段类型

   

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

4.2位段的内存分配

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

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

3)位段涉及很多不确定因素,位段是不跨平台的,可以移值的程序应该避免使用位段

举个例子

分析:

4.3位段的跨平台问题

1)int位段被当作有符号数还是无符号数是不确定的

2)位段中最大位的数目不能确定(16位机器最大16,32位机器最大32,写成27时,在16位机器下会出问题)

3)位段中的成员在内存中从左向右还是从右向左分配尚未定义

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

4.4位段的应用

网络协议中,IP数据报格式,我们可以知道很多属性只需要几个bit位就能描述,这里使用位段能实现想要的效果,同时也节省了空间

4.5位段使用的注意事项

位段中的位是bit位,一个字节8个bit位,位段的几个成员共1同一个字节,这样有些有些成员的起始位置并不是某个字节的起始位置,那么这些位置是没有地址的。

内存中每个字节分配一个地址,一个字节内部的bit位是没有地址的

所以不能对位段中的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入放在一个变量中,然后赋值给位段的成员

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

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

相关文章

六西格玛培训:企业逆袭的秘密武器!——张驰咨询

为了提升企业的运营效率、产品质量和客户满意度,六西格玛培训成为了一个不可或缺的环节。以下是企业成功实施六西格玛培训的关键步骤: 一、清晰设定培训目标 首先,企业应明确六西格玛培训的具体目标,如提升产品质量、降低成本、…

武汉城投城更公司与竹云科技签署战略协议,携手构建智慧城市新未来!

2024年5月16日,武汉城投城更公司与深圳竹云科技股份有限公司(以下简称“竹云”)签订战略合作协议,双方将深入推进产业项目合作。 签约现场,双方围绕产业项目合作方向、路径和内容等进行了全面深入交流。城投城更公司党…

Windows和Linux系统部署Docker(2)

目录 一、Linux系统部署docker 前置环境: 1.安装需要的软件包, yum-util 提供yum-config-manager功能 2.添加阿里云 docker-ce 仓库 3.安装docker软件包 4.启动 docker并设置开机自启 5.查看版本: 二、windows系统部署docker 1.查看…

如何用unittest帮你快速生成自动化测试报告?

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一直以来很多使用 pythonunittest 做自动化测试的的小伙伴都在想,unittest 这个官方库…

MFC工控项目实例之一主菜单制作

1、本项目用在WIN10下安装的vc6.0兼容版实现。创建项目名为SEAL_PRESSURE的MFC对话框。在项目res文件下添加相关256色ico格式图片。 2、项目名称:密封压力试验机 主菜单名称: 系统参数 SYS_DATA 系统测试 SYS_TEST 选择型号 TYP_CHOICE 开始试验 TES_STA…

Tasker+SendSilentMail实现钉钉自动打卡

Tasker 允许用户根据自定义的“配置文件”(Profiles),在特定的“背景”(Contexts)下,执行指定的“任务”(Tasks)。以下是关于Tasker的详细介绍: 强大的自定义能力:用户可以根据自己的需求,创建各种配置文件和任务&…

vwmare虚拟机我已复制和我已移动的区别

问题 此虚拟机可能已被移动或复制。 为了配置特定的管理和网络功能,WMware Workstation需要知道是否已移动或复制了此虚拟机。 如果您不知道,请回答“我已复制该虚拟机(P)” 我已复制 意味着复制出了一个完全相同的副本。 这两个副本可以运行在一台物理…

Linux 服务器配置 SSH 服务登录失败处理

任务目标 配置 Linux 服务器ssh远程登录失败处理机制,防止黑客爆破服务器密码 操作步骤 备份原配置文件 $ sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak $ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak安装 pam_tally2 统计登陆失败次数 # 对于Debia…

CyberDAO M级共识交流会·西安站圆满落幕:共筑Web3美好未来

CyberDAO M级共识交流会于2024年5月28日在西安隆重举行,这是一场CyberDAO精英汇聚的盛会,以同心共筑,志在必达为主题口号与DAO精英携手并进,共筑CyberDAO美好宏图。CyberDAO的使命是降低WEB3的门槛,帮助用户轻松抓住行…

每日一题《leetcode--117.填充每个结点的下一个右侧结点指针||》

https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii/ 这道题与我之前发布的题目116是一样的解题过程,只是本题所给的数组大小与116不同,这是需要注意的。 116题目链接: http://t.csdnimg.cn/3Ub02 struct Node* c…

中断向量码

中断请求引脚 INTR-可屏蔽中断请求信号输入引脚 NMI-不可屏蔽中断请求信号输入引脚 #INTA-可屏蔽中断请求信号应答引脚 IF-中断允许标志位 TF-陷阱标志位 中断向量表 由中断向量码确定中断源的类型 存储结构 中断向量地址 中断程序入口地址 示例 中断类型 内存中结构 5个…

2024-05-29 服务器开发-c++线程池与task-思考

摘要: 无论是什么系统,线程池和task都是给上层所提供的基础的功能单元。本文记录一些核心的设计思想。 线程池要面对的场景: 调用下层接口时,被IO阻塞,导致整个服务无法对外提供服务更上层调用本模块接口时,是需要做到同步&#…

为师妹写的《Java并发编程之线程池十八问》被表扬啦!

写在开头 之前给一个大四正在找工作的学妹发了自己总结的关于Java并发中线程池的面试题集,总共18题,将之取名为《Java并发编程之线程池十八问》,今天聊天时受了学妹的夸赞,心里很开心,毕竟自己整理的东西对别人起到了一点帮助,记录一下! Java并发编程之线程池十八问 经过…

月赚2万佣金的AI数字人,已成为新型带货神器,完整制作教程分享

大家好,我是设计师阿威 今天和大家分享一下用AI绘画制作数字人带货的副业创收教程,目前数字人类型的账号在短视频平台上,数字人带货能力非常强! 今天我会分享4个爆款数字人账号案例,深度讲解目前数字人的最新玩法。 …

十大排序算法【1】---冒泡排序、快速排序、选择排序、插入排序、希尔排序

动画演示 各种算法:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html 6种常见排序算法:https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html 1、冒泡排序 //1、冒泡排序Bubble Sort: 比较前后相邻的数据&#xff0c…

SQL刷题笔记day6——转战LeetCode

1 第二高的薪水 ​ 我的代码: SELECT Salary SecondHighestSalary FROM Employee ORDER BY Salary DESC LIMIT 1, 1 我的代码不满足示例2的情况:如果没有第 2 高的薪资,即表里可能只有一条记录,这个解答会被评测为 Wrong Answ…

K8s集群之 存储卷 PV PVC

默写 1 如何将pod创建在指定的Node节点上 node亲和、pod亲和、pod反亲和: 调度策略 匹配标签 操作符 nodeAffinity 主机 In,NotIn,Exists,DoesNotExist,Gt,Lt podAffinity …

从零开始学Vue3--根据目录结构自动生成路由

我们在测试或者小项目中经常遇到一个问题,就是加一个页面,就要在router.js中加一个路由,相当的麻烦,有没有办法可以根据目录结构自动生成路由呢? 想要自动生成路由,最重要的是能够获取指定目录下vue的路径…

调试记录-U盘枚举失败之LPM影响

现象 板子接部分U盘出现枚举失败,看log像是硬件信号问题,如: [ 29.186464] usb usb3-port1: Cannot enable. Maybe the USB cable is bad? [ 30.079624] usb usb3-port1: Cannot enable. Maybe the USB cable is bad? [ 30.080200]…

网络故障与排除(一)

一、Router-ID冲突导致OSPF路由环路 路由器收到相同Router-ID的两台设备发送的LSA,所以查看路由表看到的OSPF缺省路由信息就会不断变动。而当C1的缺省路由从C2中学到,C2的缺省路由又从C1中学到时,就形成了路由环路,因此出现路由不…