【C语言结构体】用户自定义类型--结构体,结构体传参,位段,联合体和枚举【图文详解】

欢迎来CILMY23的博客喔,本篇为【C语言结构体】用户自定义类型--结构体,结构体传参,位段,联合体和枚举【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注+收藏。

 前言

上一篇(http://t.csdnimg.cn/ruaRw)我们讲到C语言中,用户可以自定义类型,结构体,

 本期将讲解结构体的传参,和位段,联合体以及枚举类型。

浮点数的取值范围:float.h 整型的取值范围:limits.h

今日语句分享:一个人走慢点也并无害处,因为他的辉煌不在于行走,而在于亲身体验。

目录

一、结构体传参

二、位段

三、联合体

四、枚举 


一、结构体传参

结构体传参也分传值调用和传址调用

首先我们来看传值调用:

struct S
{int b[100];int num;
};void print1(struct S t)
{printf("%d %d %d %d\n", t.b[0], t.b[1], t.b[2], t.num);
}int main()
{struct S s = { {1,2,3},100 };print1(s);
}

结果如下:

 

我们接着来看传址调用

void print2(struct S* pt)
{printf("%d %d %d %d\n", pt->b[0], pt->b[1], pt->b[2], pt->num);
}int main()
{struct S s = { {1,2,3},100 };print2(&s);
}

结果如下:

 

二、位段

结构体传参后,我们得讲结构体的另外一个能力---位段

2.1什么是位段

位段就是以下这样的代码,它是基于结构体实现的,它的出现是为了节省空间位是二进制位的意思

struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 15;
};

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

1.    位段的成员必须是int、unsigned int 或signed int ,在C99中位段成员的类型也可以选择其他类型。
2.    位段的成员名后边有⼀个冒号和⼀个数字。 

2.2位段的大小

位段的出现既然是为了节省空间,那上面那段代码如何解读呢?

如下所示:

实际上在冒号后面的数字代表的是bit,有几个数字就有几个bit位置。 

#include <stdio.h>struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 15;
};struct B
{int _a;int _b;int _c;int _d;
};int main()
{struct A a;struct B b;printf("%d\n", sizeof(a));printf("%d\n", sizeof(b));
}

 结果如下:

 解释:

2.3位段的内存分配

 看以下这段代码:

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

 结果如下:

我们看到大小是3,但是实际上 

1.    位段中内存的空间使用是从左到右还是从右到左使用是不确定的

2.    当前面使用,剩余的空间不足下一个成员存储,是否继续使用剩余的空间是不确定的。

那我们接着看下面这段代码: 

#include <stdio.h>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;printf("%d ",sizeof(s));
}

我们假设在vs上内存分布是从右到左的 

 这里有三个字节

 首先a分配三个bit位,a的数值是10,转换成二进制是1010,因为只分配3个bit,所以存入010,b的数值是12,转换成二进制是1100,因为分配4个bit,而之前使用剩余空间足够,我们继续存入,c的数值是3,转换成二进制是011,而分配5个bit,所以存入011,其余用0补齐,d的数值是4,转换成二进制是100,分配4个bit,由于之前分配给c的bit位置不够了,我们再拿一个字节来存d,将100存入,然后再用0补齐

那在vs上到底是如何呢?

结果是显而易见的,正如我们所想的这样

2.3位段的跨平台问题 

1.    int在位段中被当成有符号数还是无符号数是不确定的。
2.    位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。)
3.    位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4.    当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第⼀个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。 

2.4 总结

位段总结:

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

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

3.    位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。 

三、联合体

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体。

3.1联合体的类型声明

 union是联合体的关键字,我们对其声明也跟结构体类似

union U
{char c;int i;
};

3.2联合体的大小和内存分布

联合体的大小:

union U
{char c;int i;
};int main()
{union U u = { 0 };printf("%d ", sizeof(union U));
}

结果如下: 

 

那为什么是4呢?这还要从联合体的成员地址看起

 

我们通过上图可以看到每个成员的地址的都是一样的 ,这说明联合体当中每个成员都是用同一个空间,所以给联合体其中一个成员赋值,其他成员的值也跟着变化。

 3.3联合体大小的计算

union Un1
{char c[5];int i;
};union Un2
{char c[7];int i;
};
int main()
{//下⾯输出的结果是什么?printf("%d\n", sizeof(union Un1));printf("%d\n", sizeof(union Un2));return 0;
}

 结果如下:

 联合体同样涉及内存对齐

所以un1对齐到8字节,同样un2也是对齐到8字节

总结:

联合的大小至少是最大成员的大小。

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。 

3.4联合体的练习 

写一个程序判断大小端字节序(这个我们之前写过:http://t.csdnimg.cn/gIUL5) 

int check_sys()
{union U{int i;char c;}u;u.i = 1;return u.c;
}

 那我们可以利用这个联合体共用一个空间的特性来解决大小端,然后设计一个函数,最后返回c 的值即可。

四、枚举 

4.1枚举的类型声明

枚举顾名思义就是一一列举。
把可能的取值一一列举。

就比如以下这段代码: 

enum Day
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};

 以上定义的enum Day是枚举类型。{}中的内容是枚举类型的可能取值,也叫枚举常量。这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

enum Day//星期
{Mon = 8,Tues = 10,Wed = 99,Thur = 54,Fri = 55,Sat = 22,Sun = 66
};

4.2枚举的优点 

我们可以使用   #define 定义常量,为什么非要使用枚举?

枚举的优点:
1.    增加代码的可读性和可维护性
2.    和#define定义的标识符比较枚举有类型检查,更加严谨。
3.    便于调试,预处理阶段会删除#define 定义的符号
4.    使用方便,⼀次可以定义多个常量
5.    枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用 

4.3枚举类型的使用

 假设我们想描述一个人的性别, 我们就可以用枚举常量给枚举类型的变量赋值。那是否可以拿整数给枚举变量赋值呢?在C语言中是可以的,但是在C++是不行的,C++的类型检查比较严格。

enum Sex
{	MALE,FEMALE,SECREAT
};int main()
{enum Sex S = FEMALE;return 0;
}

感谢各位同伴的支持,本期位段篇就讲解到这啦,如果你觉得写的不错的话,可以给个一键三连,点赞关注+收藏,若有不足,欢迎各位在评论区讨论。   

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

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

相关文章

GO—函数

Go 语言支持普通函数、匿名函数和闭包&#xff0c;从设计上对函数进行了优化和改进&#xff0c;让函数使用起来更加方便。 Go 语言的函数属于“一等公民”&#xff08;first-class&#xff09;&#xff0c;也就是说&#xff1a; 函数本身可以作为值进行传递。支持匿名函数和闭…

推荐6款SSH远程连接工具

1、Xshell 介绍&#xff1a; xshell是一个非常强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Windows平台的TELNET 协议。Xshell可以在Windows界面下用来访问远端不同系统下的服务器&#xff0c;从而比较好的达到远程控制终端的目的。 业界最强大的SSH客户机 官…

数据分析-Pandas数据的直方图探查

数据分析-Pandas数据的直方图探查 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

农产品质量追溯系统—功能介绍(2)

储藏管理 储藏信息管理对需要储藏的农产品,记录储藏的相关信息,如储藏开始时间、存放仓库、操作人员、储藏原因等; 仓库信息管理物流管理 物流公司管理对相关的物流公司信息进行登记,以便于管理和追溯; 车辆管理

我的秋招数据分析岗面经分享(京东,美团,阿里,拼多多,vivo,滴滴)

节前&#xff0c;我们社群组织了一场技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对新手如何入门数据分析、机器学习算法、该如何备战面试、面试常考点分享等热门话题进行了深入的讨论。 基于社群的讨论&#xff0c;今天…

OpenHarmony、HarmonyOS打开编辑 PDF 等操作的三方组件使用教程

项目场景: 随着数字化时代的发展,PDF 文档成为广泛应用于各行业的重要文件格式。为了提高OpenHarmony/HarmonyOS生态系统的功能性和用户体验,我们需要一款支持打开、编辑PDF文件的应用程序。 使用户能够轻松打开、浏览和编辑PDF文件。该应用将充分利用OpenHarmony/HarmonyO…

【NTN 卫星通信】卫星和无人机配合的应用场景

1 场景概述 卫星接入网是一种有潜力的技术&#xff0c;可以为地面覆盖差地区的用户提供无处不在的网络服务。然而&#xff0c;卫星覆盖范围对于位于考古或采矿地点内部/被茂密森林覆盖的村庄/山谷/靠近山丘或大型建筑物的用户可能很稀疏。因此&#xff0c;涉及卫星接入和无人驾…

HarmonyOS Full SDK的安装

OpenHarmony的应用开发工具HUAWEI DevEco Studio现在随着OpenHarmony版本发布而发布,只能在版本发布说明中下载,例如最新版本的OpenHarmony 4.0 Release。对应的需要下载DevEco Studio 4.0 Release,如下图。 图片 下载Full SDK主要有两种方式,一种是通过DevEco Studio下载…

教你用Fiddler捕获HTTPS请求

安装Fiddler 这里不特别说明了&#xff0c;网上搜索一大把&#xff0c;根据安装引导一步步安装即可。&#xff08;这里采用的是fiddler v4.6&#xff09; 配置Fiddler 1、打开fiddler配置Tools –>Telerik Fiddler Options。 2、打开HTTPS配置项&#xff0c;勾选“Captur…

ctf_show笔记篇(web入门---爆破)

爆破 21&#xff1a;直接bp抓包跑字典&#xff0c;需base64加密 22&#xff1a;可用工具跑也可用浏览器找还可以用网上做好的域名查找去找 23&#xff1a;此题需跑脚本已经附上自写脚本 最后跑出来六个答案一个一个尝试得到答案为3j import hashlibm "0123456789qwert…

C++_AVL树

目录 1、AVL的概念 2、平衡因子的调整概念 3、AVL树的插入 3.1 调整平衡因子代码实现 3.2 右旋操作 3.2 左旋操作 3.3 双旋-先右旋再左旋 3.4 双旋-先左旋再右旋 3.5 旋转操作的小结 4、AVL的验证与实现 结语 前言&#xff1a; 在C中&#xff0c;AVL树是在二叉搜索…

旧的Spring Security OAuth已停止维护,全面拥抱新解决方案Spring SAS

Spring Authorization Server 替换 Shiro 指引 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护&#xff0c;该项目将不会再进行任何的迭代 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用作为 SpringBoot 3.0 的最新…

如何使用naive 做一个模态框的方式

1.我的问题使用了一个table 表格&#xff0c;在表格中设置俩个按钮 最后做出来的效果 <template><div><h1>测试文件</h1><!-- 表格 --><n-data-table :columns"columns" :data"data" :pagination"pagination" …

Linux内核队列queue.h

文章目录 一、简介二、SLIST单向无尾链表2.1 介绍2.2 操作2.3 例子 三、STAILQ单向有尾链表四、LIST双向无尾链表五、TAILQ双向有尾链表六、CIRCLEQ循环链表七、queue源码参考 一、简介 queue.h是一个非常经典的文件&#xff0c;定义了一系列宏的操作&#xff0c;它定义了一系…

笔记72:关于IMU(惯性测量单元)传感器的作用【不涉及公式推导】

一、IMU传感器是什么&#xff1a; 惯性测量单元IMU&#xff08;Inertial Measurement Unit&#xff09;是一种使用【加速度计】和【陀螺仪】来测量【物体三轴姿态角&#xff08;空间姿态&#xff09;】的装置&#xff1b;IMU在坐标系的每个坐标轴上&#xff0c;均安装有1个陀螺…

Vue2:用node+express部署Vue项目

一、编译项目 命令 npm run build执行命令后&#xff0c;我们会在项目文件夹中看到如下生成的文件 二、部署Vue项目 接上一篇&#xff0c;nodeexpress编写轻量级服务 1、在demo中创建static文件夹 2、将dist目录中的文件放入static中 3、修改server.js文件 关键配置&…

DFA还原白盒AES密钥

本期内容是关于某app模拟登录的,涉及的知识点比较多,有unidbg补环境及辅助还原算法,ida中的md5以及白盒aes,fart脱壳,frida反调试 本章所有样本及资料均上传到了123云盘 llb资料官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 目录 首先抓包 fart脱壳 加密位置定位…

win11安装nodejs

一、下载安装包 链接: https://pan.baidu.com/s/1_df8s1UlgNNaewWrWgI59A?pwdpsjm 提取码: psjm 二、安装步骤 1.双击安装包 2.Next> 3.勾选之后&#xff0c;Next> 4.点击Change&#xff0c;选择你要安装的路径&#xff0c;然后Next> 5.点击Install安装 二、…

学生云服务器腾讯云_腾讯云学生学生_腾讯云学生云主机

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

基于扩散模型的图像编辑:首篇综述

AIGC 大模型最火热的任务之一——基于 Diffusion Model 的图像编辑(editing)领域的首篇综述。长达 26 页&#xff0c;涵盖 297 篇文献&#xff01;本文全面研究图像编辑前沿方法&#xff0c;并根据技术路线精炼地划分为 3 个大类、14 个子类&#xff0c;通过表格列明每个方法的…