位段 联合体 枚举

news2024/10/7 6:50:38

在这里插入图片描述

Hello好久不见,今天分享的是接上次结构体没有分享完的内容,这次我们讲讲位段 枚举和联合体的概念以及他们的用法。

2.1 什么是位段
位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是 int、unsigned int 或signed int 。
2.位段的成员名后边有一个冒号和一个数字。

总的来说,位段和结构体很相似,但是不同的地方就是它表示的大小是位,大小是比特位,不是字节,这样的作用就是减少内存大小,还有就是增加效率。

那接下来让我们来看一个位端吧

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

这就是我们位段的基本样子,一个冒号加数字,数字表示的就是大小,单位是比特位。
我们也可以将它放入函数中来看一下它的大小。
我们可以将它们放入我们函数当中,用sizeof来测试,看下面的代码

#include<stdio.h>
struct A
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;
};
int main()
{
	printf("%zd ", sizeof(struct A));
	return 0;
}

我们可以看到上代码在我们控制台上的结果是8
在这里插入图片描述
位段的内存分配

  1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
//一个例子
#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;
	return  0;
}
//空间是如何开辟的?

我们来看上面的一个例子,来了解它在VS上是怎么开辟空间的

因为Vs是小端,我们从低地址开始往后动,在假设我们先用数据的低位开始往后动。
在这里插入图片描述
我们这是根据它的大小进行猜,因为它所占的字节大小就是三个字节,所以我们进行猜设它是从数据的低位开始,而且我们不是每个字节都要用到,当一个字节中不能存储我们后面比特位大小的时候我们跳到后面的字节开始使用,我们可以在VS中用内存来查看我们的结果

在这里插入图片描述
转换到16进制是620304这个数字,我们现在来看一下在内存的存储吧

在这里插入图片描述

我们可以看到的结果是和我们编译器上是一样的,但是还是会有问题,那就是位段时不能跨平台的,第一是因为它有很多不确定性,比如我们不知道它对数据的使用是怎么使用的,是从小到大还是从左到右,这都是不确定的,所以它有很多的不确定性

2.3 位段的跨平台问题

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

总结:
跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。
在这里插入图片描述
这就是我们位段的使用场景,相当于是包装数据,比如我们微信发消息的时候要表白一位女生,首先我们要确定这位女生的用户名,这就相当于我们图中的IP地址,如果没有这个Ip地址,我们就可能不知道发给谁,可能就发给自己的好兄弟,那这样可要产生大误会了,而我们的数据也不是直接发过去的,要进行我们最后的包装才可以,我们进行包装的时候,如果用的不是位段的话,上面的版本好每个都需要一个整型大小,那这样不是浪费,我们所占的空间越大,运行速度就越慢,我们发数据是通过网络协议栈的,这就是相当于我们的高速公路如果用int包装的话,那就是相当于大卡车,但是如果是用位段进行包装的话,那就是相当于小汽车,通行速度也就快了。

3. 枚举

枚举顾名思义就是一一列举。
把可能的取值一一列举。
比如我们现实生活中:
一周的星期一到星期日是有限的7天,可以一一列举。

性别有:男、女、保密,也可以一一列举。
月份有12个月,也可以一一列举
这里就可以使用枚举了。

那我们来使用一下枚举吧(枚举关键字是enum)
在这里插入图片描述
我们可以看到其实枚举就是整型常量,说到常量大家还记得有多少,一个是字面常量,还有就是const修饰的长常变量,还有就是枚举常量了
3.2 枚举的优点
为什么使用枚举?
我们可以使用 #define 定义常量,为什么非要使用枚举?
枚举的优点:

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量

这里在讲一下我们经常哟美好的define,我们也可以讲上面的三元素写成

#define GREEN 0
#define RED 0
#define BLUE 0

但是为什么枚举方便调试呢,这里是有原因的 当我们define的时候,我们调试就直接替换掉了,所以会不方便调试,枚举你叫方便调试,还有就是方便,比如我们要枚举一个周,那我们直接写就行了,但是如果我们define,要写七次,看起来就有点麻烦,所以不建议这样写。

enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;               //

我们在C语言中可以这样写,但是在语法检查严格的C++就不能这样写了
4. 联合(共用体)

  • 4.1 联合类型的定义

联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

4.2 联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

#include<stdio.h>
//联合类型的声明
union Un
{
	char c;
	int i;
};

int main()
{
	//联合变量的定义
	union Un un;
	//计算连个变量的大小
	printf("%d\n", sizeof(un));
	return 0;
}

通过运行发现我们的结果是4个字节大小那说明我们char其实和我们的int公用一个个字节。
4.2 联合的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)

union Un
{
 int i;
 char c;
};
union Un un;
// 下面输出的结果是一样的吗?
printf("%d\n", &(un.i));
printf("%d\n", &(un.c));
//下面输出的结果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);

可以看到的是其实他们的地址是一样的,这里更加说明了联合体是共用同一块空间的

那我们还记不记得之前我们来测试机器大小端是怎样计算的呢,相信有一部分人记得,另一部分又忘记了,那在写一次吧

#include<stdio.h>
int check_sys()
{
	int a = 1;
	return *((char*)&a);
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

那现在我们也可以用联合体来进行测试

#include<stdio.h>
int check_sys()
{
	union
	{
		char c;
		int i;
	}u;
	u.i = 1;
	return u.c;
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

联合体使用范围就是有点小,特殊情况才使用我们来看一下下面这张图

在这里插入图片描述
这里我们看图,发现每次都需要重新定义一个结构体,这样浪费空间就很大,那我们就可以这样写

在这里插入图片描述
这样写就能节省很多空间了,那今天的内容就分享到这里,我们下次再见

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

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

相关文章

Unity下tga和png格式图片打包成AB包大小和加载速度测试

测试素材 测试素材&#xff0c;一张tga格式&#xff0c;一张png格式&#xff0c;他们的图像尺寸一样都是8K图。 两张图在AssetBundles里显示 Tga格式的图明显大很多&#xff0c;我们打包成ab包看看。 在PC 打包后看&#xff0c;明显大小一样&#xff0c;我们进行ab包加载&am…

通俗易懂讲解拥塞控制

文章目录 前言一、拥塞控制是什么&#xff1f;二、什么是拥塞窗口&#xff1f;和发送窗口有什么关系呢&#xff1f;三、慢启动四、阻塞避免算法五、拥塞发生状态时的算法以及快速重传以及快速恢复总结 前言 TCP的拥塞控制&#xff0c;以前觉得老复杂了&#xff0c;今天重温了一…

HTML - input type=file 允许用户选择多个文件

效果 示例 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><!-- When the multiple Boolean attribute is specified, the file input allows the user to select more than o…

【漏洞复现】企望制造 ERP命令执行

漏洞描述 由于企望制造 ERP comboxstore.action接口权限设置不当&#xff0c;默认的配置可执行任意SQL语句&#xff0c;利用xp_cmdshell函数可远程执行命令&#xff0c;未经认证的攻击者可通过该漏洞获取服务器权限。 免责声明 技术文章仅供参考&#xff0c;任何个人和组织…

Python经典练习题(二)

文章目录 &#x1f340;题目一&#x1f340;第二题&#x1f340;第三题&#x1f340;第四题&#x1f340;第五题 &#x1f340;题目一 古典问题&#xff1a;有一对兔子&#xff0c;从出生后第3个月起每个月都生一对兔子&#xff0c;小兔子长到第三个月后每个月又生一对兔子&am…

【操作系统笔记二】链接阶段ELF文件

链接阶段&#xff1a;符号解析 链接阶段主要包含&#xff1a; 符号解析重定位 一般情况下&#xff0c;每个 C 文件可以看成一个程序模块&#xff0c;比如下边的main.c就是一个程序模块 #include <stdio.h>extern int shared; int sum(int *a, int n); int array[2] …

【C语言】指针的进阶(四)—— 企业笔试题解析

笔试题1&#xff1a; int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } 【答案】在x86环境下运行 【解析】 &a是取出整个数组的地址&#xff0c;&a就表示整个数组&#xff0c;因此…

oracle11g升级12c

目录 背景&#xff1a;oracle11.2.0.4升级至12.2.0.1版本 当前数据库版本 1&#xff09;上传12g安装包&#xff0c;解压开始安装 2&#xff09;不勾选 3&#xff09;升级数据库 4&#xff09;下一步 5&#xff09;修改路径11.2.0换成12.2.0 6&#xff09;下一步 7&…

shardingjdbc分库分表数据均衡性讨论

问题引入 最近一个业务系统中&#xff0c;因为数据量很大&#xff0c;经过技术选型&#xff0c;综合权衡选择了sharding-Jdbc&#xff0c;本文主要讨论的是分库分表的表达式 我们有一个批次总表A&#xff0c;还有一个明细表B&#xff0c;我们需要对明细表B进行水平拆分&#…

论文总结《A Closer Look at Few-shot Classification Again》

原文链接 A Closer Look at Few-shot Classification Again 摘要 这篇文章主要探讨了在少样本图像分类问题中&#xff0c;training algorithm 和 adaptation algorithm的相关性问题。给出了training algorithm和adaptation algorithm是完全不想关的&#xff0c;这意味着我们…

瑞芯微RK3568:Debian系统如何安装Docker

本文基于HD-RK3568-IOT评估板演示Debian系统安装Docker&#xff0c;该方法适用于RK356X全系产品。 HD-RK3568-IOT评估板基于HD-RK3568-CORE 工业级核心板设计&#xff08;双网口、双CAN、5路串口&#xff09;&#xff0c;接口丰富&#xff0c;适用于工业现场应用需求&#xff…

怒刷LeetCode的第13天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;滑动窗口 方法二&#xff1a;哈希表和双指针 方法三&#xff1a;动态规划 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;深度优先搜索&#xff08;DFS&#xff09; 方法二&#xff1a;树结构 …

rv1126-rv1109-RkLunch.sh

RkLunch.sh是个脚本,来自哪里 书接上回:rv1126-rv1109-瑞芯微的 IPC 程序_旋风旋风的博客-CSDN博客 修改之后 屏蔽了两行之后,就没有开机自启rklunch了: # [ -f /oem/RkLunch.sh ] && source /oem/RkLunch.sh 就是运行source /oem/RkLunch.sh 这里就跑了RkL…

基于微信小程序的驾校报名系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信小程序端的主要功能有&#xff1a;驾校教练的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码…

动手学深度学习(pytorch版)第二章-2.2数据预处理Note-pandas

1. 创建 import osos.makedirs(os.path.join(.., data), exist_okTrue) data_file os.path.join(.., data, house_tiny.csv) with open(data_file, w) as f:f.write(NumRooms,Alley,Price\n) # 列名f.write(NA,Pave,127500\n) # 每行表示一个数据样本f.write(2,NA,106000\…

平板用的触控笔什么牌子好?性价比高的触控笔推荐

随着平板电脑的普及&#xff0c;越来越多用户为了方便都选择了电容笔&#xff0c;电容笔已经完全代替了我们的手指&#xff0c;并且使我们的书写速度得到了极大的提升。然而&#xff0c;因为其的独特的重力压感功能与芯片技术&#xff0c;导致了原装笔的售价一直居高不下&#…

深入探析NCV7356D1R2G 单线CAN收发器各项参数

NCV7356D1R2G深力科是一款用于单线数据链路的物理层器件&#xff0c;能够使用多种具碰撞分解的载波感测多重存取 (CSMA/CR) 协议运行&#xff0c;如博世控制器区域网络 (CAN) 2.0 版。此串行数据链路网络适用于不需要高速数据的应用&#xff0c;低速数据可在物理介质部件和微处…

用selenium和xpath定位元素并获取属性值以及str字符型转json型

页面html如图所示&#xff1a; 要使用xpath定位这个div元素&#xff0c;并且获取其属性data-config的内容值。 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Optionshost127.0.0.1 port10808 …

线程安全,与多线程的应用

一、线程安全 1.什么是线程安全 2.用程序模拟线程安全问题 public class Account {private double money;//余额private String cardId;//卡号public Account() {}public Account(double money, String cardId) {this.money money;this.cardId cardId;}public void drawMone…

LeetCode 1993. 树上的操作:大模拟

【LetMeFly】1993.树上的操作&#xff1a;大模拟 力扣题目链接&#xff1a;https://leetcode.cn/problems/operations-on-tree/ 给你一棵 n 个节点的树&#xff0c;编号从 0 到 n - 1 &#xff0c;以父节点数组 parent 的形式给出&#xff0c;其中 parent[i] 是第 i 个节点的…