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

news2024/11/15 15:36:50

欢迎来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.coloradmin.cn/o/1483986.html

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

相关文章

AJAX实例

AJAX - Asynchronous JavaScript and XML - 异步的JavaScript与XML&#xff0c;不是一门新技术&#xff0c;只是一个新的术语。&#xff08;老技术新玩法&#xff09; - 使用AJAX&#xff0c;网页能够将增量更新呈现在页面上&#xff0c;而不需要刷新整个页面。 - 虽然X代表…

Docker知识点总结二

四、 Docker 架构 Docker使用客户端-服务器(C/S)架构模式&#xff0c;使用远程API来管理和创建Docker容器。 介绍&#xff1a; 1、Docker的客户端client&#xff0c;我们在命令行发送一些信息(命令)给Docker服务端。2、中间这个就是Docker的服务端&#xff0c;在这个服务端里面…

jupyter 用pyecharts进行数据分析

一、jupyter和pyecharts下载和打开 因为我是用的pycharm&#xff0c;所以我直接在pycharm项目终端中下载pip install jupyter,pip install pyecharts 在你下载的项目路径中输入jupyter notebook 之后会进入页面 Jupyter 具体使用参考这个链接&#xff1a;Jupyter Notebook基本…

微信小程序 ---- 慕尚花坊 商品管理

商品管理 01. 配置商品管理分包 思路分析&#xff1a; 随着项目功能的增加&#xff0c;项目体积也随着增大&#xff0c;从而影响小程序的加载速度&#xff0c;影响用户的体验。 因此我们需要将 商品列表 和 商品详情 功能配置成一个分包&#xff0c; 当用户在访问设置页面…

【c语言】基础数据类型

文章目录 1、什么数据类型2、常量3、变量4、整型数据5、浮点型数据6、字符型数据7、字符串数据 1、什么数据类型 ​ 在生活中&#xff0c;裁缝做衣服需要用到不同的化纤、棉花、丝绸等布料&#xff0c;炒不同的菜需要油、盐等不同的配方&#xff0c;而程序员在编写程序时也需要…

我在代码随想录|写代码Day31 | 贪心算法总结篇 | 贪心终结一题

&#x1f525;博客介绍&#xff1a; 27dCnc &#x1f3a5;系列专栏&#xff1a; <<数据结构与算法>> << 算法入门>> << C项目>> &#x1f3a5; 当前专栏: << 算法入门>> 专题 : 数据结构帮助小白快速入门算法 &#x1f4…

对程序、进程、线程、并发、并行、高并发概念的讲解

一、概述 程序、进程、线程、并发、并行和高并发是计算机科学领域中非常重要的概念。 了解进程、线程、并发和并行的概念&#xff0c;可以更好地利用计算机的多核处理器和并行计算能力&#xff0c;提高计算机性能。 了解进程和线程为操作系统中的资源管理提供了基础&#xff…

VMwareWorkstation17.0搭建深度Deepin23Beta3系统虚拟机(完整安装步骤详细图文教程)

VMwareWorkstation17.0搭建深度Deepin23Beta3系统虚拟机&#xff08;完整安装步骤详细图文教程&#xff09; 一、Deepin23Beta3深度操作系统1. Deepin深度操作系统介绍2.Deepin官网3.Deepin深度操作系统的下载地址3.1 Deepin20.9深度操作系统3.1 Deepin V23 Beta3(Unstable)深度…

java项目打包运行报异常:xxxxx-1.0-SNAPSHOT.jar中没有主清单属性

pom.xml中加入这段话即可 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.4</version><executions><execution><…

Siamrpn++论文中文翻译(详细!)

SiamRPN: Evolution of Siamese Visual Tracking with Very Deep Networks SiamRPN&#xff1a;具有非常深度网络的Siamese视觉跟踪的进化 【siamrpn论文地址】 https://arxiv.org/abs/1812.11703 摘要 基于Siamese网络的跟踪器将跟踪表示为目标模板和搜索区域之间的卷积特征…

基于ssm疫情期间高校防控系统+vue论文

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;学生信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广大…

贪吃蛇(C语言)步骤讲解

一&#xff1a;文章大概 使用C语言在windows环境的控制台中模拟实现经典小游戏 实现基本功能&#xff1a; 1.贪吃蛇地图绘制 2.蛇吃食物的功能&#xff08;上&#xff0c;下&#xff0c;左&#xff0c;右方向控制蛇的动作&#xff09; 3.蛇撞墙死亡 4.计算得分 5.蛇身加…

【LeetCode:230. 二叉搜索树中第K小的元素 + 二叉树 + 递归】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

YOLOv9:Learning What You Want to Learn Using Programmable Gradient Information

YOLOv9&#xff1a;Learning What You Want to Learn Using Programmable Gradient Information 摘要 今天的深度学习方法关注的是如何设计最合适的目标函数&#xff0c;使模型的预测结果最接近ground truth的真实情况。同时&#xff0c;必须设计一个适当的体系结构&#xff…

CSS 【详解】响应式布局(含 rem 详解)

响应式布局&#xff1a; 同一页面在不同的屏幕上有不同的布局&#xff0c;即一套代码自适应不同的屏幕。 为什么 rem 能用于实现响应式布局&#xff1f; px 绝对长度单位&#xff0c;不同客户端表现都相同&#xff0c;不具有响应式em 相对长度单位&#xff0c;相对于父元素的 f…

【博图TIA-Api】通过Excel自动新建文件夹和导入FB块

【博图TIA-Api】通过Excel自动新建文件夹和导入FB块 说明思路准备获取Excel表格内文件名和FB块名等信息新建文件夹部分筛分获取的文件夹数据&#xff0c;去掉重复内容创建文件夹 导入FB块导出FB块的xml文件查找需要放置的文件夹导入块 说明 续上一篇文章&#xff0c;这次是根据…

Python爬虫——Urllib库-3

目录 ajax的get请求 获取豆瓣电影第一页的数据并保存到本地 获取豆瓣电影前十页的数据 ajax的post请求 总结 ajax的get请求 获取豆瓣电影第一页的数据并保存到本地 首先可以在浏览器找到发送数据的接口 那么我们的url就可以在header中找到了 再加上UA这个header 进行请…

【Easyx】easyx从入门到精通 — 初步入门

easyx 初步入门 1 安装easyx图形库2 如何使用Easyx3 效果初试4 基本图形绘制4.1 绘制点4.2 绘制直线4.3 绘制圆形4.4 绘制矩形4.5 绘制椭圆4.6 绘制圆角矩形4.7 绘制扇形 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇…

mTSL: netty单向/双向TLS连接

创建证书 不管是单向tls还是双向tls(mTLS)&#xff0c;都需要创建证书。 创建证书可以使用openssl或者keytool&#xff0c;openssl 参考 mTLS: openssl创建CA证书 单向/双向tls需要使用到的相关文件: 文件单向tls双向tlsServer端Client端备注ca.key----需要保管好&#xff0…

Linux高负载排查最佳实践

在Linux系统中&#xff0c;经常会因为负载过高导致各种性能问题。那么如何进行排查&#xff0c;其实是有迹可循&#xff0c;而且模式固定。 本次就来分享一下&#xff0c;CPU占用过高、磁盘IO占用过高的排查方法。 还是那句话&#xff0c;以最佳实践入手&#xff0c;真传一句话…