自定义类型详解(结构体+位段+枚举+联合)

这篇具有很好参考价值的文章主要介绍了自定义类型详解(结构体+位段+枚举+联合)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

你好,我是史丰源
欢迎你的来访,希望我的博客能给你带来一些帮助。

我的Gitee: 代码仓库☀️

我的联系方式:
QQ:1756786195
邮箱:Marksky126@outlook.com🌐

🌟一、结构体

1.1 结构体的基础知识

1.11我们为什么需要结构体?

C语言中的类型是单一的,如果我们需要去形容一个复杂对象,就需要结构体.

之所以叫结构体,可以看作它是一个立体的存储单元,将各种各样的成员(特点)集合为一体(结构体).

而里面的成员 可以是各种各样类型的变量

1.2 结构体的声明

struct Student
{
	int age;
	char name[20];
	int id;
};

以上就是一个学生结构体的声明。

1.3 结构体的特殊声明(匿名结构体)

struct
{
	int a;
	char b;
}s;

匿名结构体顾名思义就是省略了结构体标签。
并且只能用一次。
一般在定义结构体类型的同时定义结构体变量。

注意:匿名结构体的成员如果一样,在编译器看来也是不同的类型的结构体。
举例子:

struct
{
	int a;
	char b;
}s;
struct
{
	int a;
	char b;
}x,*p;//p为结构体指针
p=&s;//行为非法,编译器还是会把它们当作两个不同的结构体,
//所以不能地址赋值地址。

1.4 结构的自引用

举例子:

struct Node
{
	int data;
	struct Node* next;
};//一定不要丢掉*

1.5 结构体变量的定义和初始化

  1. 普通初始化
    举例子:
struct student
{
	char name[20];
	char id[12];
}s={"zhangsan","1234"};
  1. 嵌套初始化
struct price
{
	struct student s;
	float c;
}s={{"zhangsan","1234",57.7}};

1.6 结构体的内存对齐🔥

1.61 如何计算结构体的内存大小?

内存对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数: 编译器的默认一个对齐数与该结构体成员大小的较小值。
(后面会讲到怎样修改默认对齐数。)

  1. 结构体总大小为所有结构体成员中对齐数最大值的整数倍。

🚩4.若有嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体大小就是所有最大对齐数(含嵌套结构体)的整数倍。

注意:对齐数不是成员大小,笔者第一次听这个概念时,分不清两者😓

举例子:

自定义类型详解(结构体+位段+枚举+联合)
上面这个例子就是常见的结构体计算大小问题。
我们再用一个例子来解释 规则4
举例子:
自定义类型详解(结构体+位段+枚举+联合)
规则4 的易错点:嵌套的结构体对齐到自己的最大对齐数的整数倍
一定要记住是自己的,在示例中就是s1自己的最大对齐数— 4,所以要找4的整数倍。

1.62 为什么存在结构体内存对齐?

因为结构体是一个不同类型数据的集合,当我们在读取这个结构体数据时
会出现以下的情况:
自定义类型详解(结构体+位段+枚举+联合)
但是如果我们进行内存对齐:
自定义类型详解(结构体+位段+枚举+联合)
所以进行内存对齐,数据的读取次数会减少
从而来实现效率最大化。

这个过程就是利用空间换时间的做法⚡️

所以我们在设计一个结构体时,尽量让占用空间小的变量集中在一起

1.7 修改默认对齐数

#pragma pack(4);
struct S
{
	char c;
	double d;
}//答案为16
#pragma pack()//取消修改默认对齐数,还原为默认。

1.8结构体传参

结构体传参时,建议不要传值,因为传值时会造成大量的时间、空间浪费。
建议传址,只有一个地址的大小,效率更高。

🌟二、位段

2.1 什么是位段?

位段与结构体类似,但是有两点不同。

  1. 位段的成员必须是int,unsigned int,signed int,char(类属于整型家族)。
  2. 位段成员后方跟一个冒号与一个数字(比特位)。

强调:位段不进行内存对齐。

举例子:

struct A
{
	int _a:2;//2个比特位
	int _b:5;//5个比特位
	int _c:10;//10个比特位
	int _d:30;//30个比特位
	//共47个字节
}

位段A的大小是 8 字节。

2.2 位段的内存分配

  1. 位段的空间上是按照4个字节或1个字节开辟的。
  2. 位段的内存分配不确定。
    举个分配不确定的例子:
struct A
{
	char _b:3;
	char _c:6;
} 
struct A a = {0};//将结构体A中元素置为0
a._b = 10;

自定义类型详解(结构体+位段+枚举+联合)

2.3 位段的跨平台问题(不安全因素)

  1. int 位段是被当作signed int 还是unsigned int是不确定的。

  2. 位段中最大位的数目不确定并且可移植性不好,若是32位机器开32个比特位,在16位机器就会出问题。

  3. 位段中分配内存是从左到右,还是从右到左不确定。

  4. 当一个位段的位不够用时,是开辟新的位还是利用剩余的位,这也是不确定的。

综上:位段的效率很高,但是有利必有弊,位段也有跨平台的问题会出现。
大家需根据特定需求使用位段。

三、枚举类型(枚举:一一列举。)

3.1 枚举类型的定义

举例子:

enum Sex
{
	MALE,//0
	FEMALE,//1
	SECRET//2
};

{ }中的内容都是枚举类型的可能取值,也叫做枚举常量。

这些可能取值都是有值的,默认从0开始,依次递增。
但我们也可以给它初始化。
举例子:

enum I
{
	M=9,
	K=7
};

注意 :初始化只能在枚举类型内,而不能在其他地方初始化。

3.2 枚举的优点(与#define相比)

  1. 增加代码的可读性与可维护性
    举例子:
enum Color
{
	RED = 5,
	GREEN = 4
    BLUE = 3
};
int main()
{
	enum Color c=RED;
}
  1. 和#define定义的标识符相比 枚举类型有类型检查(检查的是类型,而不是值),更为严谨

PS:关于这个问题大家可以去看这篇文章:C语言的枚举类型检查问题.

  1. 限制了范围(封装)
    在一定范围内才能使用。

  2. 便于调试(不会被替换)
    在预编译时,#define 所定义的常量会直接变为数字(调试的代码与源代码不一样),而枚举类型则不会(调试代码与源代码一致)。

  3. 使用方便,一次可以定义很多个常量

3.3 枚举的使用

举例子:

enum Color
{
	RED = 5,
	GREEN = 4,
	BLUE = 5
};
enum Color clr = BLUE

四、联合(共用体)

具体场景具体使用

4.1 联合类型的定义(union)

联合类型定义的变量包含很多成员,特点就是这些成员共用一块空间(因此也称为共用体)

4.2 联合的特点

  1. 共用一块空间。
  2. 在改变一个变量时,其他变量同时被改。
  3. 成员在同一时间只能使用一个,不能同时被使用。
  4. 联合类型变量的大小至少是最大成员的大小(4.3中演示)

4.3 联合大小的计算

1.联合大小至少是最大成员的大小
2.当最大成员大小不是最大对齐数的整数倍时,要对齐到最大对齐数的整数倍。
举例子:

union Un1
{
	char c[5];//1*5==5 不是最大的
	int i;//4
};//最终大小为8,4为最大对齐数
union Un2
{
	short c[7];//2*7==14 不是最大的
	int i;//4
};//最终大小为16,对齐数为4

在找最大对齐数时,要看联合体成员类型,确认对齐数,比如说:Un1的char为1,int 为 4,而不是看后面的数组个数来计算。
找最大对齐数的倍数 ——最靠近并且能容纳所有变量大小的数。

感谢你看到这里,希望我的博客对你有帮助。
我是一名大学生,在学习编程的道路上,我们一起努力!
自定义类型详解(结构体+位段+枚举+联合)文章来源地址https://www.toymoban.com/news/detail-401789.html

到了这里,关于自定义类型详解(结构体+位段+枚举+联合)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【无标题】自定义类型:位段,枚举,联合

    在结构体进阶中,我们详细介绍过了结构体。 接下来就是结构体实现位段的功能。 位段的声明和结构是类似的,但有两个不同: ①: 位段的成员必须是int、unsigned int或signed int。 ②: 位段的成员名后边有一个冒号和一个数字。 比如: A就是一个位段类型! 那位段A的大小是

    2024年02月15日
    浏览(29)
  • 【C语言】——自定义类型详解:结构体,枚举,联合

    大家好,今天为大家分享一下C语言中的那些自定义类型:结构体,枚举,联合,还有之前可能不曾了解的结构体内存对齐、位段等知识点!!! 一、结构体 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 结构的声明 : 例如描述一个学生

    2024年02月07日
    浏览(36)
  • 详解C语言自定义类型(结构体,枚举,联合)

    ❤️ 作者简介 :RO-BERRY 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识,对纯音乐有独特的喜爱 📗 日后方向 : 偏向于CPP开发以及大数据方向,如果你也感兴趣的话欢迎关注博主,期待更新 🎄结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不

    2024年02月16日
    浏览(26)
  • C语言——自定义类型详解[结构体][枚举][联合体]

    我打算把结构体、枚举、联合体的重点内容总结一下,方便后期复习的时候能够更快,更准确的去拾取遗忘的知识。也希望能给大家起到借鉴的作用,不足的地方,请多多包涵。(不足的地方,也希望大家能够指出来) 结构体是一些值的集合,这些集合称为成员变量,结构体

    2024年02月13日
    浏览(29)
  • 【C语言:自定义类型(结构体、位段、共用体、枚举)】

    C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的, 假设我想描述学生,描述⼀本书,这时单⼀的内置类型是不⾏的。描述⼀个学生需要名字、年龄、学号、身高、体重等;描述⼀本书需要作者、出版社、定价等。C语言为

    2024年02月05日
    浏览(31)
  • 【C语言进阶(七)】自定义类型--结构体,位段,联合

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C语言学习分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多C语言知识   🔝🔝 文章目标: 本篇文章着重给大家讲解: 结构体内存对齐的知识 并且介绍位段,联合的内容 最后对这一板块做出拓展 结构体,位段和

    2024年02月15日
    浏览(29)
  • 全网最细的自定义类型详解(结构体,枚举,联合),友友们快来接收吧

    各位csdn的友友们肯定都掌握了c语言中 char,short, int, long, float, double的类型 ,这些都是我们c语言中的一些内置类型,其实c语言是可以允许我们创造一些类型的,今天阿博就带领友友们一起掌握这些新的自定义类型😊😊😊 结构体类型的声明 注意最后那个分号千万不能丢哦!

    2023年04月17日
    浏览(38)
  • 自定义类型之结构体,枚举,联合

    在初识结构体一文中,我们对结构体已经有所了解. 1.结构体的声明, 2.结构体变量的定义与初始化, 3.结构体传参. 其实结构体是一个很重要的内容,在数据结构中,应用十分广泛.所以学好 结构体 也是十分重要的! 匿名结构体是一种省略struct后面的类型名的一种结构体类型. 这种情

    2023年04月09日
    浏览(32)
  • 自定义类型:结构体,枚举,联合 (2)

    位段的出现就是为了节省空间。 位段的声明和结构是类似的,有两个不同: 1.位段的成员必须是 int、unsigned int 或signed int 。 2.位段的成员名后边有一个冒号和一个数字。 比如:  A就是一个位段类型,位段的位指的是二进制位,成员名后的数字代表着占空间的多少个bit位,

    2024年02月05日
    浏览(30)
  • 自定义类型:结构体、枚举、联合体

    结构体是一种自定义的数据类型,它由多个不同类型的成员变量组成,结构体可以将多个相关的数据打包在一起,方便进行管理和处理。 定义形式: struct 结构体名{ 类型 成员名1; 类型 成员名2; //更多的成员变量 }; 如描述一个学生: struct Stu这样就和int类型一样,都是数

    2024年02月16日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包